Single Responsibility Principle (SRP)
Each class should have a single responsibility. That means that there should be only one reason to change it. This is one of the SOLID principles.
Usage
π Guideline
Single Responsibility Principle: Each class should have a single responsibility.
A class should be designed in such a way that it has only one reason to change. It should have a well-defined and focused responsibility, making it easier to understand, maintain, and modify.
π οΈ How to Apply
- Identify clear responsibilities: Define specific tasks and responsibilities for each class. Use meaningful names that reflect their purpose. π―
- Separate concerns: Avoid mixing unrelated functionalities within a single class. Delegate tasks to other classes to maintain a focused and modular codebase. π§©
- Refactor when necessary: If a class grows too large or takes on multiple responsibilities, consider splitting it into smaller, more specialized classes. β»οΈ
Pros and Cons
π Pros
- Improved readability: Classes with single responsibilities are easier to understand, as they focus on a specific task or behavior. π
- Enhanced maintainability: When a class has a single responsibility, modifications and updates become simpler and less error-prone. π οΈ
- Enhanced reusability: Well-defined responsibilities allow for greater code reuse by promoting modular design and efficient development. π
π Cons
- Increased complexity: Dividing code into multiple classes can introduce additional complexity, requiring careful coordination and communication between them. π§©
- Potential performance impact: Separating responsibilities may result in additional function calls or inter-class communication, potentially affecting runtime performance. β±οΈ
- Higher development effort: Applying the Single Responsibility Principle may require additional upfront effort to analyze and refactor the codebase. β°
Examples
β Bad
// Bad: A class with multiple responsibilities
class UserManager {
constructor() {
// ...
}
getUser(id) {
// Retrieves user data from the database
}
updateUser(id, data) {
// Updates user data in the database
}
sendEmail(user, message) {
// Sends an email to the user
}
}
β Good
// Good: Separating responsibilities into distinct classes
class UserDatabase {
constructor() {
// ...
}
getUser(id) {
// Retrieves user data from the database
}
updateUser(id, data) {
// Updates user data in the database
}
}
class EmailService {
constructor() {
// ...
}
sendEmail(user, message) {
// Sends an email to the user
}
}
References
𧱠SOLID Principles
SOLID is an acronym for five other class-design principles:
- Single Responsibility Principle (SRP)
- Open-Closed Principle (OCP)
- Liskov Substitution Principle (LSP)
- Interface Segregation Principle (ISP)
- Dependency Inversion Principle (DIP)
π Related principles
- Open/Closed Principle: Complements the Single Responsibility Principle by promoting the separation of concerns and facilitating future modifications. π
- Liskov Substitution Principle: Aligns with the Single Responsibility Principle by emphasizing the need for well-defined and consistent behavior. βοΈ
- Interface Segregation Principle: Supports the Single Responsibility Principle by advocating for focused and cohesive interfaces. π
- Dependency Inversion Principle: Works hand in hand with the Single Responsibility Principle to decouple classes and facilitate maintainability.βοΈ
- Don't Repeat Yourself (DRY): Aligns with the Single Responsibility Principle by reducing code duplication within classes and enforcing a focused and concise codebase. π