Single Responsibility

One Responsibility per Unit of Code with an Example

SOLID OOP Wednesday, May 21, 2014

Each class should have only one responsiblity, Right... I'd say it's not just about every class having one single responsibility. I would also add that every unit of code should have only one responsibility e.g. class PersonService will deal with business logic related to people but each of the methods of that class will have their own responsibility and so will a certain project. It comes down to scope.

Let's work a case on which I worked a few weeks ago. While I was working on a benefits calculator, one of the requirements was that a list of other potential benefits would display on the results page, but that list should be different considering the circumstances of the person's household e.g. if a person has a income lower than £12K and has 2 children (made up case) then they are potentially entitled to a particular benefit. You get the picture.

Some developers could be tempted to create a method somewhere to return that list of potential benefits and use a bunch of if statements to get the correct list. Whilst that could work, I would not agree with such an approach as that bring potential costly implications maintaing that bit of software, especially the benefits systems being so complex and ever-changing.

Remember we're talking about the responsibility principle? Each if statement will have an effect on the final list of benefits. Each of those units of code may be moved to a separate rule class. Something along these lines:


public interface IRule
{
  Benefit Execute(HouseholdCircumstances circumstances);
}

public class TVLicenseDiscountRule : IRule
{
  public Benefit Execute(HouseholdCircumstances circumstances)
  {
    if (circumstances.Income < 12000 && circumstances.Children.Count > 2)
	{
	  return new TVLicenceDiscount();
	}
  }
}

This difference in implementation requires a bit more work than just creating a method with a bunch of if statements, true, but it also makes maintainability much easier and less costly and dare I say enjoyable.

Think of it this way, a new developer comes along and needs to fix a bug. Do you think it would be easy to read and maintain that or smaller classes?

What if he's asked to add another potential benefit entitlement. He'll have to *change* the method just to *add* functionality. Whenever a developer changes code, chances are he/she might break something (that's why they invented tests) but wouldn't it be better to simply create a new rule class for it? That way, you're guaranteed (with limited certainty) not to break functionality or create bugs in the current code base. Which brings us to the Open/Closed principle.