Quote for the Week

"Learn to enjoy every moment of your life"

Friday, January 23, 2015

S.O.L.I.D Architecture principle in C#

What is SOLID?



SOLID are five basic principles whichhelp to create good software architecture. SOLID is an acronym where:-
  1. S stands for SRP (Single responsibility principle
  2. O stands for OCP (Open closed principle)
  3. L stands for LSP (Liskov substitution principle)
  4. I stands for ISP ( Interface segregation principle)
  5. D stands for DIP ( Dependency inversion principle)
Day 1:

"S" - Single Responsibility Principle.


The Single Responsibility Principle (SRP) states that:

A class should have only a single responsibility. Only one potential change in the software's specification should be able to affect the specification of the class.

This means that every class, or similar structure, in your code should have only one job to do. Everything in that class should be related to a single purpose. Our class should not be like a Swiss knife wherein if one of them needs to be changed then the entire tool needs to be altered. It does not mean that your classes should only contain one method or property. There may be many members as long as they relate to the single responsibility.

The Single Responsibility Principle gives us a good way of identifying classes at the design phase of an application and it makes you think of all the ways a class can change. A good separation of responsibilities is done only when the full picture of how the application should work. Let us check this with an example.

public class UserService  
{  
   public void Register(string email, string password)  
   {  
      if (!ValidateEmail(email))  
         throw new ValidationException("Email is not an email");  
         var user = new User(email, password);  
  
         SendEmail(new MailMessage("mysite@nowhere.com", email) { Subject="HEllo foo" });  
   }
   public virtual bool ValidateEmail(string email)  
   {  
     return email.Contains("@");  
   }  
   public bool SendEmail(MailMessage message)  
   {  
     _smtpClient.Send(message);  
   }  
}   

It looks fine, but it is not following SRP. The SendEmail and ValidateEmail methods have nothing to do within the UserService class. Let's refract it.

public class UserService  
{  
   EmailService _emailService;  
   DbContext _dbContext;  
   public UserService(EmailService aEmailService, DbContext aDbContext)  
   {  
      _emailService = aEmailService;  
      _dbContext = aDbContext;  
   }  
   public void Register(string email, string password)  
   {  
      if (!_emailService.ValidateEmail(email))  
         throw new ValidationException("Email is not an email");  
         var user = new User(email, password);  
         _dbContext.Save(user);  
         emailService.SendEmail(new MailMessage("myname@mydomain.com", email) {Subject="Hi. How are you!"});  
  
      }  
   }  
   public class EmailService  
   {  
      SmtpClient _smtpClient;  
   public EmailService(SmtpClient aSmtpClient)  
   {  
      _smtpClient = aSmtpClient;  
   }  
   public bool virtual ValidateEmail(string email)  
   {  
      return email.Contains("@");  
   }  
   public bool SendEmail(MailMessage message)  
   {  
      _smtpClient.Send(message);  
   }  
}   

Let's see remaining things on tomorrow's post.

No comments: