Single Responsibility Design Principle in SOLID

SRP = Single Responsibility Principle

It is composed of 3 words.

  • Single(One)
  • Responsibility 
  • Principle (Fundamental Guide Line)

What is SRP?

  • Applicable: A class or module should focus on doing one thing and doing it well & it should have a single responsibility.
  • Not Applicable: It should not be responsible for unrelated multiple tasks.

Why do we need SRP?

The SRP is often associated with the concept of "high cohesion", which means that the elements within a class are closely related and work together to achieve a single purpose.

Benefits of SRP

  1. Separation of Concern: Every class has a single purpose.
  2. Easy Debugging: Due to point No. 1.
  3. Reusability: Code written in 1 class can be re-used by another class.
  4. Increased Stability: Fewer changes in any class as each class is used for a single motive.
  5. Easy Collaboration: Team members can work on different classes or components independently because the responsibilities are well-defined.
  6. Less Knowledge Transfer Need: Code written using SRP is generally more readable and understandable because the intent and functionality of each class are clear.

Example

Suppose we have a scenario: when we create a user, we need to do 3 activities.

  • Add user
  • Verify Email
  • Send Email

Code Without SRP

public class UserRelatedService
{
   public void AddUserFunction(string email, string password)
   {
                if (!CheckEmailFunction(email))
    {
        SendEmailFunction(string email);
    }
   }
   public virtual bool CheckEmailFunctiona(string email)
   {
   }
   public bool SendEmailFunction(string email)
   {
   }
}

In the above code, you will notice that email-related functions are in user classes.

Since high cohesion is not between the user & email.

It's violating SRP.

Code is written using SRP

We have separated 3 methods of adding users, validating, and Sending emails into two classes.

Two Types of functionality

  1. User related functionality: Add, Update, Delete 
  2. Email Related Functionality: Check, Send
public class UserService
{
    EmailService emailService;

    public UserService(EmailService aEmailService)
    {
        emailService = aEmailService;
    }

    public void Register(string email, string password)
    {
        if (!emailService.ValidateEmail(email))
            throw new ValidationException("Email is not valid");

        Console.WriteLine("User Added/Register.");
        emailService.SendEmail(new MailMessage("[email protected]", email) { Subject = "Hi. How are you!" });
    }
}
public class EmailService
{
    SmtpClient smtpClient;

    public EmailService(SmtpClient aSmtpClient)
    {
        smtpClient = aSmtpClient;
    }

    public bool ValidateEmail(string email)
    {
        Console.WriteLine("Validating Email.");
        return email.Contains("@");
    }

    public void SendEmail(MailMessage message)
    {
        //_smtpClient.Send(message);
        Console.WriteLine("Email Sent.");
    }
}
  • User Class has only user-specific functionality & Email Class has only email-specific functionality.
  • User class uses using function of email class instead of recreating them.

Download the Source code from below git repository below.