-
Notifications
You must be signed in to change notification settings - Fork 0
Single Responsibility Principle
Subrata Sahoo edited this page Jul 19, 2024
·
5 revisions
A class should have one and only one reason to change, meaning that a class should have only one job.
A class should be responsible for only one actor or entity. If a class is catering to multiple actors/entities, it could be breaking the single responsibility principle.
- Enhanced readability: Small & clean classes.
- Improved maintainability: Changes are isolated to specific aspect of the application.
- Simplified testing: Classes can be tested in isolation making unit testing more straight forward & reliable.
- Reduced risk of errors: By isolating responsibilities, changes to one part of the system will not induces errors in unrelated areas.
- Better reusability: Classes more focused on a single responsibility are more likely to be reusable in other parts of the application.
| Problem | Description | Solution |
|---|---|---|
| Over-Fragmentation | Applying SRP too rigidly can lead to an excessive number of small classes, each handling a single responsibility. This can make the system fragmented and harder to navigate, as it might require interacting with many small components. | Balance is key. Meaningful responsibilities and avoiding creation of too many classes for minor responsibilities. Group related responsibilities where appropriate. |
| Increased Complexity | Breaking down responsibilities can sometimes lead to increased complexity in the codebase. The interactions between numerous small classes can become complicated. | Ensure that the design remains understandable. Use descriptive class names and maintain clear boundaries between responsibilities to keep complexity |
| Class Explosion | Following SRP can lead to a proliferation of classes, which might make the codebase harder to manage and understand. | Regularly review of design to ensure that classes are not being overly fragmented. Using composition and well-defined interfaces to keep the number of classes reasonable. |
| Difficulty in Identifying Responsibilities | Determining what constitutes a single responsibility can be subjective and challenging. Misidentifying responsibilities can lead to classes that are either too broad or too narrow. | Thoughtful design and refactoring. Involve multiple perspectives, including peer reviews, to ensure that responsibilities are correctly identified and assigned. |
| Refactoring Overhead | Applying SRP might require significant refactoring of existing code, which can be time-consuming and introduce new risks. | Apply SRP incrementally. Refactor the codebase gradually, focusing on one area at a time to manage risks and reduce overhead. |
| Potential for Over-Engineering | Striving to adhere to SRP in every aspect can sometimes lead to over-engineering. This might involve creating overly complex abstractions for very simple tasks. | Apply SRP pragmatically. Ensure that abstractions and class separations genuinely improve maintainability and not just complicate the design. |
| Increased Indirection | Breaking down responsibilities might introduce additional layers of indirection which can sometimes lead to performance concerns or make debugging more difficult. | Ensure that the added indirection does not adversely impact performance or clarity. Profile and optimize when necessary. |
| Misalignment with Other Principles | Striving for SRP might sometimes conflict with other design principles like the Open/Closed Principle (OCP) or the Interface Segregation Principle (ISP). | Consider all SOLID principles together when designing systems. Ensure that the application of SRP aligns with the overall design goals and principles. |
Book class in WithOutSRP folder violates the single responsibility principle by handling multiple responsibilities holding book data, saving book data to database, printing & emailing.
In the refactored example in the WithSRP folder:
- The Book class is only responsible for holding book data.
- The BookRepository class is responsible for saving book data to a database.
- The PrintingService class is responsible for printing.
- The EmailService class is responsible for sending email notifications.
By separating these responsibilities, each class now has a single reason to change, making the system more modular, maintainable, and easier to understand.