Use when creating or modifying classes, modules, or functions. Use when feeling pressure to add functionality to existing code. Use when class has multiple reasons to change.
A class should have only one reason to change.
Every module, class, or function should have responsibility over a single part of functionality. If you can describe what a class does using "AND", it has too many responsibilities.
NEVER add functionality that introduces a second reason to change.
No exceptions:
Violating SRP under pressure is still violating SRP.
Describe your class in one sentence. If it contains "AND", split it.
| Description | Verdict |
|---|---|
| "Handles user authentication" | ✅ Single responsibility |
| "Handles authentication AND sends emails" | ❌ Two responsibilities |
| "Manages orders AND processes payments AND tracks inventory" | ❌ Three responsibilities |
List why this class might need to change:
// ❌ BAD: UserManager - 4 reasons to change
class UserManager {
login() {} // Auth logic changes
updateProfile() {} // Profile requirements change
sendEmail() {} // Email provider changes
trackAnalytics() {} // Analytics requirements change
}
// ✅ GOOD: Split by responsibility
class AuthService { login() {} }
class ProfileService { updateProfile() {} }
class NotificationService { sendEmail() {} }
class AnalyticsService { track() {} }
When pressured to violate SRP, follow this:
"Just make it work quickly"
Response: Creating a god class takes the same time as creating focused classes. The "quick" solution creates technical debt that costs 10x more later.
Action: Create separate classes. It's not slower.
"The class already exists, just add to it"
Response: Adding to a bloated class makes it worse. The fact that it's already wrong doesn't justify making it more wrong.
Action: Create a new focused class. Refactor the existing one if time permits.
"My tech lead said put it all in one class"
Response: Respectfully push back with evidence. If overruled, document your concern and comply—but NEVER silently create god classes.
Action:
"I'd recommend splitting this because [specific reason].
If we keep it together, we'll likely need to refactor when [consequence].
Should I proceed with the split, or document this as tech debt?"
"While you're in there, also add X"
Response: New functionality = new class (or existing appropriate class).
Action: "X belongs in its own service. I'll create XService."
If you notice ANY of these, you're about to violate SRP:
All of these mean: Split the class.
When you encounter an existing god class:
// Found: OrderService with 500 lines handling orders, payments, inventory, emails
// ❌ WRONG: Add shipping logic to OrderService
// ✅ RIGHT: Create ShippingService, note that OrderService needs refactoring
| Excuse | Reality |
|---|---|
| "It's faster to put it in one class" | It's not. You type the same code either way. |
| "Small classes are over-engineering" | Small classes are correct engineering. |
| "It's just one more method" | That's how god classes start. Every time. |
| "We can refactor later" | You won't. Tech debt compounds. |
| "The class is already big" | That's a reason to stop, not continue. |
| "It's related functionality" | Related ≠ same responsibility. |
| "Section comments help navigate" | If you need navigation, class is too big. |
| Symptom | Action |
|---|---|
| Class does X AND Y | Split into XService and YService |
| Adding unrelated method | Create new class |
| File > 200 lines | Look for extraction opportunities |
| Multiple reasons to change | One class per reason |
| "Manager/Handler/Processor" name | Be more specific or split |
One class. One responsibility. One reason to change.
When pressured to violate this: push back, document, or create the right structure anyway.
God classes are never the answer, regardless of time pressure, existing code, or authority demands.