Cleaner code with single responsibility principle

SRP is the first principle of out the SOLID principles and it’s defining that each object should have only one responsibility. In other words, objects should not encapsulate logic taking care of multiple responsibilities at one time. By dividing code into more isolated classes with it’s own responsibilities, you’re also transforming the logic from being tight coupled to being loose coupled.

Not taking the principle in account often times leads to spaghetti code as large classes with unclear purposes are gonna be created. Such code is impossible to maintain in the long run. On the other hand creating classes with isolated functionality effectively communicate their intent and how should they be used to the development team.

Why is it important?

As you can imagine, the codebase expands and grows as time goes. Clearly defined responsibilities of objects help developers to keep the codebase maintainable even if it’s becoming more complex over time in terms of:

  • improved readability and reduced time to understand the code,
  • easier future modifications to the code,
  • shareability of particular objects among several projects,
  • testability.

Now let’s take a closer look at each of the points above.

Improved readability

There’s a rule that says developers tend to read the code ten times more than actually writing it. I’m not quite sure it’s exactly ten times but I can confirm large portion of developers' time is to read the code. It’s because when a new feature is being implemented the developer must have a clear understanding what the code he/she is about to modify is doing.

Having classes doing one specific job definitely helps the code to be more readable and understandable as the developer is not concerned with any side effects caused by the fact that the responsibilities are tight coupled are mixed together. It also gives the developer much more confidence in what the code is doing.

Easier future modifications to the code

When following SRP, introducing modifications becomes simpler because of these reasons:

  • you know exactly where the new code should be added to - to an existing class corresponding with functionality you’re about to add or to a new class if a suitable class does not exist yet (you don’t want to add the functionality randomly to any class you want)
  • you feel more certain because there’s a less probability to break something by modifying code that mixes various unrelated functionalities together.

Many times I’ve seen classes consisting of thousands lines of code, tens of methods that tied together too many unrelated responsibilities until the point the class became confusing and thus unmaintainable resulting in higher risks of breaking things. Such classes had to be refactored later to get back the needed maintainability.

Shareability of code among several projects

You’re really doing yourself a favour when you’re separating specific logic to the classes where it actually belongs because you can then share the code with other modules or projects easily.

This relates mainly to the library functionalities. Let’s compare two situations there when your college asks you to hand him/her part of your functionality (e.g. bank transfer transactions matching) to his/her project:/her part of your functionality (e.g. bank transfer transactions matching) to his/her project:

  • there’s a one class handling everything - from common functionality like mailbox message fetching, specific functionality of parsing particular e-mail messages to database operations consisting of saving the matched transaction,
  • you applied SRP and the classes are structured in the following way - there’s a common class for mailbox message fetching, a class (ideally interfaced for several bank message types) that parses the mailmessage and a class that handles database operations and a facade that encapsulates business logic behind the whole process.

What you can do in the first case is to hand over the whole class to your college but I guess he/she won’t be very happy with it as the code will is tight coupled to specific DB engine resulting in a lot of work to manually filter out logic that fits the other project./she won’t be very happy with it as the code will is tight coupled to specific DB engine resulting in a lot of work to manually filter out logic that fits the other project./she won’t be very happy with it as the code will is tight coupled to specific DB engine resulting in a lot of work to manually filter out logic that fits the other project.

On the other hand in the second case you can hand over just the classes including common functionality like mailbox messages fetching, parsing the mailbox message and maybe even the facade if correct interfaces are used (more about that in “Dependency Inversion” principle).

Testability

Developing tests for large classes is a very difficult task. Splitting classes into smaller ones with specific responsibilities enables you to increase code coverage in a shorter time as it’s always easier to test smaller chunks of code than larger blocks.

Conclusion

SRP is a great way to make the codebase much cleaner, easier to maintain and more testable-friendly by simply structuring the code into smaller classes with one specific purpose.