Single Responsibility
Problem
Components grow into thousand-line files that handle data fetching, validation, formatting, UI rendering, and business logic simultaneously. Changes to one aspect require understanding and potentially breaking everything else, and testing becomes impossible because every feature is tangled together.
Solution
Design each module or component to have one reason to change. This creates focused, cohesive units that are easier to understand and less likely to have unintended side effects.
Example
This demonstrates separating different responsibilities into focused functions, where each function has a single clear purpose and reason to change, making code easier to understand, test, and maintain.
// Bad - multiple responsibilities mixed together
function UserManager() {
fetchUser(); // Data fetching
validateUser(); // Business logic
renderUser(); // UI rendering
}
// Good - single responsibility per function
function fetchUser() { /* fetch logic - only handles data retrieval */ }
function validateUser() { /* validation logic - only handles business rules */ }
function renderUser() { /* render logic - only handles UI presentation */ }
Benefits
- Makes code easier to understand by focusing each unit on one purpose.
- Simplifies testing by isolating functionality.
- Reduces the risk of unintended side effects when making changes.
- Improves code reusability across different contexts.
Tradeoffs
- Can lead to many small files or functions, increasing project complexity.
- May create indirection that makes following code flow harder.
- Requires judgment about what constitutes a “single responsibility”.
- Can be taken too far, fragmenting cohesive functionality.