Under this statement hides principle which developers should be familiar with, since creating functions/methods. This principle states, that each class should be responsible for one specified thing. Let’s have a look at code below:
class Person
{
public string Name { get; set; }
public string LastName { get; set; }
public string City { get; set; }
public string Street { get; set; }
public int HouseNumber { get; set; }
public string Email { get; set; }
public Person(string name, string lastname, string email)
{
Name = name;
LastName = lastname;
Email = ValidateEmail(email);
}
public static bool ValidateEmail(string email)
{
string pattern = @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$";
bool isValid = Regex.IsMatch(email, pattern);
return isValid;
}
}
What exactly is going on above? We have declared a class, which has tons of incompetently declared properties and ValidateEmail method which do not fit. Here comes the question – why is that?
First of all – properties City, Street or HouseNumber from the beginning don’t sound like Person’s property – they sound more like an address. We can assume, that given person may live there, but it is not certain – from programming point of view – these properties are not related with class name. Secondly – class Person contains ValidateEmail method which shouldn’t be responsible for Person type.
So what should be done? Crucial thing to achieve single responsibility principle is to split whole class to smaller classes, where every single class has it’s responsiblity :
//creating Address class and re-creating properties
class Address
{
public string City { get; set; }
public string Street { get; set; }
public int HouseNumber { get; set; }
}
//creating Person class with Address's class properties
class Person
{
public string Name { get; set; }
public string Lastname { get; set; }
public string Email { get; set; }
public Address PersonAddress { get; set; }
public Person(string name, string lastname, string email)
{
Name = name;
Lastname = lastname;
Email = email;
}
}
//separated ValidateEmail() method, converted to class with unchanged e-mail validation logic
class EmailValidator
{
public static bool ValidateEmail(string email)
{
string pattern = @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$";
bool isValid = Regex.IsMatch(email, pattern);
return isValid;
}
}
// running Main method
public static void Main(string[] args)
{
Console.WriteLine("Enter e-mail address");
string email = Console.ReadLine();
if (ValidateEmail(email))
{
Console.WriteLine("E-mail address correct");
}
else
{
Console.WriteLine("E-mail address incorrect");
}
}
But why is that principle so important?
Lets assume, that our code is much bigger than shown above, and there somehow is a bug in our code. What would happen if there are many functionalities in our class that are responsible for things that these class shouldn’t be responsible for? Exactly – lots of code to review, overthinking what comes from etc. While having less functionalities but consistent with what class is responsible for, there is much less code to review and much less mess to clean up.