top of page
Writer's pictureViq Hus

Single-Responsibility-Principle-SRP

Updated: Jul 27, 2023

The Single Responsibility Principle (or SRP) is one of the principles as part of SOLID - five design principles intended to help write cleaner code, that is code which is more understandable, flexible and maintainable.

A class should have only one reason to change. – Robert C.Martin

In essence, a reason to change is a responsibility, and your software modules, whether it be a method, class etc. should do one thing and one thing only. We want to give the module a single reason to ever change. The main benefit of implementing this principle is to decouple code; if you make a change in a module, you don’t want it to have a knock-on effect on other items; this kind of coupling leads to fragile designs that break in unexpected ways when changed. Our aim is to make our code highly cohesive (a strongly-related set of functions performed by a module) with low coupling (a low degree of dependency between modules).

A single class is tightly coupled within itself, which when used by other class must be used entirely. When other class use this particular class and that class changes, all the depending classes must be retested as they have all been affected by the new changes. If a class has poor cohesion, and a part of it is changed, all depending classes will need to be retested, even though only certain classes utilize the affected changed area. Instead, if the class was highly cohesive, it would have fewer dependencies, therefore any change would have a lesser impact on the system. We should break down things that are likely to change, and encapsulate them into separate modules, so they have less of an effect when altered. If you can think of more than one reason for changing a class, then it probably has more than one responsibility and is breaking the SRP.

A common example is the Swiss army knife:





The Swiss army knife has many tools such as scissors, toothpick and nail trimmer, but how practical/useful is it?

Example

Consider the following Spam service, which takes some parameters and sends spam emails.


public class SpamService {
  public void SendSpam(string email) {
    if (!email.Contains("@") || !email.Contains(".")) {
      throw new Exception("Email is not valid!!");
    }
    SmtpClient client = new SmtpClient();
    client.Send(new MailMessage("mysite@nowhere.com", email) {
      Subject = "You’ve Won!"
    });
  }
}

While the SpamService does send spam, it also does extra things too. If we wanted to start sending the email in a different manner, this class would need to change, and that would be fine. But what if we wanted to add more validation to the email? The class would also need to change in that case, therefore has more than one reason to change. We should move this validation out into a separate class:


public class EmailService {
  public void Validate(string email) {
    if (!email.Contains("@") || !email.Contains(".")) {
      throw new Exception("Email is not valid!!");
    }
  }
}

Then our SpamService class will look like:


public class SpamService {
  EmailService _emailService;
  public SpamService(EmailService emailService) {
    _emailService = emailService;
  }
  public void SendSpam(string email) {
    _emailService.Validate(email);
    SmtpClient client = new SmtpClient();
    client.Send(new MailMessage("mysite@nowhere.com", email) {
      Subject = "You've Won!"
    });
  }
}

Now each class will have one, and only one, reason to change.

Problem

The issue then arises, what exactly is a “reason to change”, or a “responsibility”. You could argue that our original example code was correct and valid and that validating the email is the SpamService's responsibility. Else, if you strictly following the single responsibility rule, this could lead to having many single line methods, which would cause an unnecessary code bloat, so you need to maintain a balance between single responsibilities and over extracting code into tiny modules. There are no hard and fast rules here.

Conclusion

The SRP rule should always be applied when possible. How exactly you apply this rule will depending on your team as to what exactly is deemed a single responsibility. Overall in the long run, it will help to minimise changes, ease the maintenance of the code, and most importantly: keep the code clean.

1 view0 comments

Recent Posts

See All

Comments


I'm a lead software developer currently working at AG Grid in London.

Technologies I'm currently focused on include Salesforce, .NET Core, Angular, SQL, React and Azure.

Other than that, in my spare time I watch the Arsenal at the Emirates, work on side projects or watch sports. Oh, and I'm also a part-time body builder.

You can contact me at vh@viqas.co.uk

profile.jpg

About Viqas Hussain

bottom of page