"Hello and welcome to class today ๐" is a phrase I've never heard directed at me ๐, even if I was greeted by a teacher that way, my reaction would have been ๐. Lots of people hate classrooms and classes in general. In software development, functional programmers and newbie developers don't exactly like classes either. Classes are strongly linked with object-oriented programming (OOP).
In my last article, I promised we'd look at "class" as it applies to backend development. This is going to be fairly quick. Classes are used to implement the creation of objects. In OOP, everything is an object and can be objectified (I don't mean this the way you're looking at it ๐ ).
A relatable explanation
A lot of development requires the creation of objects in order to embody whatever it is we're trying to build. For example, you, as a registered user of Hashnode, are an object as far as the code of Hashnode is concerned. In order to use OOP to create Hashnode (note that I don't know exactly how Hashnode is built), we will need a class to embody you and me.
So let's say we create a class called "user". The user class is used to conceptualize us, users of the platform. Now we have to ask ourselves what characteristics a user will have. A human being will have characteristics like eyes, limbs, nose, mouth, tongue, etc. (under normal circumstances). Netizens (literally anyone with access to the internet), like you and I, must also have certain characteristics.
A Conceptual Implementation
On Hashnode , you have a profile picture, a bio, and you may have posts, followers, etc. All of the above are some of your characteristics as a user of Hashnode. On the code side, we create a class to conceptualize who we are as users of the platform. Every "characteristic" I mentioned would be made into a property. A property is then responsible for holding and giving out values that are directly assigned to it.
For example, your profile picture property is responsible for holding a link to your profile image or your profile image itself, which is why whenever you log into Hashnode, your profile picture displays. By logging in, you indirectly ask your device to ask the server to provide all your properties, the server asks the code for the values and presents everything to you (through your device). It's kind of like how you're served food on a plate (the plate being your device in this case), by a waiter (which is the server in this case).
Classes can also be used to package data for other purposes, like sending values to an API, receiving values from an API, holding values received from a database, creating the schema of a database (through code-first entity framework migrations), generating values within an application and temporarily storing it, among other feats. Classes are central to the work of developers who use OOP. Classes can be manipulated in a lot of ways depending on the situation, and are a convenient tool in backend software development.
Let's See Some Code
Creating classes isn't that hard, all you need is the access modifier, the keyword "class", and the class name. Other values that may be used in defining a class are whether or not it's static, the datatype, among others. A simple "user" class is illustrated below.
public class User:IdentityUser
{
public string Id { get; set; }
[Required(ErrorMessage = "First name cannot be empty")]
[Display(Name = "First Name")]
[StringLength(100, ErrorMessage = "{0} must be at least {2} characters long.", MinimumLength = 2)]
public string FirstName { get; set; }
[Required(ErrorMessage = "Last name cannot be empty")]
[Display(Name = "Last Name")]
[StringLength(100, ErrorMessage = "{0} must be at least {2} characters long.", MinimumLength = 2)]
public string LastName { get; set; }
public string FullName => $"{FirstName} {LastName}";
[Required(ErrorMessage = "Email cannot be empty")]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
public DateTime DateOfBirth { get; set; }
[Required(ErrorMessage = "Password cannot be empty")]
[DataType(DataType.Password)]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 8)]
[Display(Name = "Password")]
[RegularExpression("^((?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])|(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[^a-zA-Z0-9])|(?=.*?[A-Z])(?=.*?[0-9])(?=.*?[^a-zA-Z0-9])|(?=.*?[a-z])(?=.*?[0-9])(?=.*?[^a-zA-Z0-9])).{8,}$", ErrorMessage = "Passwords must be at least 8 characters and contain at 3 of 4 of the following: upper case (A-Z), lower case (a-z), number (0-9) and special character (e.g. !@#$%^&*)")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The passwords do not match.")]
public string ConfirmPassword { get; set; }
[Required(ErrorMessage = "You have to declare your nation of origin")]
public int CountryId { get; set; }
[ForeignKey("CountryId")]
public Country Country { get; set; }
public string? Bio { get; set; }
public string? Image { get; set; }
}
Finally
It's important that you learn about classes as they relate to SOLID principles and OOP, while functional programming is still quite popular, OOP is definitely a very widespread paradigm of programming that deserves some attention and can further your development as a software engineer. The code snippet above can be used to create the schema for a user table through code first entity framework migration, it also contains some level of input validation, data annotation, and Regular Expression (REGEX).