The single responsibility principle states that a function or class or module should have one responsibility and one reason to change. According to Robert C. Martin’s Clean Code, A handbook for agile software craftsmanship.
The Single Responsibility Principle is one of the more important concepts in Object-Oriented design. Yet oddly, SRP is often the most abused design principle.
I will demonstrate the SRP violation at the class and functional level using code snippets through this article. Later we will refactor those snippets based on SRP concepts. I will try to keep it as simple, stupid as possible.
Classes should have one reason to change, no we are not going to repeat the exact text from the SRP definition. The best examples to demonstrate the SRP violation are listed below.
- Performing complex business logic in view class, which is responsible for the data visualization.
- Performing data access logic in the business class, which is responsible to perform business logic.
- Performing business logic in data access class, which is responsible to provide persistent data access.
- Accessing the business services through domain class, which is responsible to persist the data.
Let’s look at a simple class that violates the SRP by doing both data access and business validations in the same class.
In the above code function
getUserAccountById(Long id) performs data access operation and function
verifyUserAccount(UserAccount userAccount) performs business validations in the same class
Let's refactor the above code based on the Single responsibility principle.
After refactoring the class
UserAccountRepository will be responsible for performing the data access functionalities and the class
UserAccountService will be responsible for performing the business logic.
Functions should do one thing, they should do it well, they should do it only.
Functions should be small. According to Robert C. Martin’s Clean Code.
The best examples to demonstrate the SRP violation of function are shown below.
The above function
enableUserAccountWithRoles(UserAccount userAccount) did two things. First, it enables the user account, and second, it assigns roles for the user account.
Let's refactor the above function by applying SRP.
After refactoring the function
enableUserAccount(UserAccount userAccount) will do the only thing, that enables the user account. Similarly, the function
enableRoles(UserAccount userAccount) will also do the only thing, which enables roles for the user account.
The problem is that many of us think that we are done once the program works, we fail to scale the maintainability. At the same time, many developers fear that a larger number of small single-purpose functions and classes make it more difficult to understand the big picture.
So the question is, Do you want your tools organized into toolboxes with many small drawers each contained well-defined and well-labeled components? Or do you want a few drawers that you just toss everything into?.
The single responsibility principle is a widely recognized design strategy that ensures every component of the application does one thing, only one thing.
Thank you all for letting me share my knowledge with you. Have a good day ahead.
Kindly let me know your feedback/correction/doubts in the comment box.