Rob Sutherland’s Musings on Life, Code, and Anything Else

SRP: Single Reponsibility Principle

This is the S of the SOLID series.

Definition from Wikipedia: "A class should have only a single responsibility, that is, only changes to one part of the software's specification should be able to affect the specification of the class."

In practice, this can be difficult to achieve. It is sometimes hard to define what "single thing" the class is doing. Something that thing is easy to define, but the single thing requires a lot of code to accomplish. This is where all of the patterns working together makes for a better solution.

One place to watch out for is a single, often static, class that is a catch-all for various functionality. When the methods stop making sense together, it is time to refactor your code.

Take a look at the class you are working on. Do all the member names make sense together? Does it sound like it is doing one thing, or several things? What do the memember names have in common? Where do they differ? Should there be a different organization and dependencies that do most of the work? (Take a look at I and D for additional information.)

Another consideration is related to testing. How may tests would I have to write to test this class? Would those tests all seem very similar? Would I have to setup Mocks for a lot of things, or just a couple? Would it feel like I'm testing different aspects of the same thing or testing different things altogether?

If you were to break out the IDataProvider into more granular interfaces that had only one responsibility each, how many interfaces would you end up with? Are there multiple, justified ways to break up the interface into multiple interfaces?

There are benefits of a class that follows the Single Responsibility Principle:

  1. It has fewer reasons to change and therefore often changes less
  2. It often has a more meaningful name that indicates its purpose
  3. It is often smaller (less code), more coherent and easier to understand
  4. It is easier to test since all of its functionality is related, the tests are often similar and don't require a lot of extra setup for unrelated dependencies
  5. It is easier to compose (A Design Pattern) with other classes to make a more robust system
  6. Its primary logic isn't hidden away in a base class

Having classes that follow SRP doesn't mean there will be less code in the project overall. There may actually be more. However, the gains of having the clearer lines of separation will greatly increase the readability and maintainability of the code.