single-responsibility-principle
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSingle Responsibility Principle (SRP)
单一职责原则(SRP)
Overview
概述
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.
一个类应该只有一个变更理由。
每个模块、类或函数都应该只负责单一功能领域的部分。如果你能用“和”来描述一个类的功能,说明它承担了过多职责。
When to Use
适用场景
- Creating any new class, module, or service
- Adding methods to existing classes
- Reviewing code that "does multiple things"
- Feeling pressure to "just add it here"
- 创建任何新类、模块或服务
- 向现有类添加方法
- 评审“身兼数职”的代码
- 迫于压力想“直接加在这里”的时候
The Iron Rule
铁律
NEVER add functionality that introduces a second reason to change.No exceptions:
- Not for "it's faster this way"
- Not for "it's just one more method"
- Not for "refactoring would take too long"
- Not for "my tech lead said so"
- Not for "it's already in production"
Violating SRP under pressure is still violating SRP.
绝不添加会引入第二个变更理由的功能。无一例外:
- 不要以“这样更快”为借口
- 不要以“只是多一个方法”为借口
- 不要以“重构太费时间”为借口
- 不要以“技术主管这么说”为借口
- 不要以“已经上线了”为借口
迫于压力违反SRP仍然是违反SRP。
Detection: The "AND" Test
检测方法:“和”测试
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 |
用一句话描述你的类。如果句子里包含“和”,就拆分它。
| 描述 | 结论 |
|---|---|
| “处理用户认证” | ✅ 单一职责 |
| “处理认证和发送邮件” | ❌ 两个职责 |
| “管理订单、处理支付和跟踪库存” | ❌ 三个职责 |
Detection: Reasons to Change
检测方法:变更理由清单
List why this class might need to change:
typescript
// ❌ 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() {} }列出这个类可能需要变更的理由:
typescript
// ❌ 错误示例:UserManager - 4个变更理由
class UserManager {
login() {} // 认证逻辑变更
updateProfile() {} // 个人资料需求变更
sendEmail() {} // 邮件服务商变更
trackAnalytics() {} // 数据分析需求变更
}
// ✅ 正确示例:按职责拆分
class AuthService { login() {} }
class ProfileService { updateProfile() {} }
class NotificationService { sendEmail() {} }
class AnalyticsService { track() {} }Pressure Resistance Protocol
抗压指南
When pressured to violate SRP, follow this:
当你迫于压力要违反SRP时,请遵循以下步骤:
1. Time Pressure
1. 时间压力
"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.
“先快速搞定就行”
回应: 创建一个全能类和创建多个专注类所花的时间是一样的。这种“快速”方案会产生技术债务,后续成本会是现在的10倍。
行动: 创建独立的类。并不会更慢。
2. Sunk Cost Pressure
2. 沉没成本压力
"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.
“这个类已经存在了,直接加进去就行”
回应: 向臃肿的类添加功能只会让情况更糟。它本身就设计不合理,不能成为继续错下去的理由。
行动: 创建一个新的专注类。如果时间允许,重构现有类。
3. Authority Pressure
3. 权威压力
"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?"“我的技术主管说把所有内容都放在一个类里”
回应: 有理有据地提出反对意见。如果被驳回,记录你的顾虑并执行,但绝不要默默创建全能类。
行动:
“我建议拆分这个类,因为[具体原因]。
如果我们保留在一个类里,当[后果]发生时,我们可能需要重构。
我是应该进行拆分,还是将此记录为技术债务?”4. Scope Creep
4. 范围蔓延
"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."
“既然你已经在改了,顺便把X也加上吧”
回应: 新功能应该对应新类(或已有合适的类)。
行动: “X应该属于独立的服务。我会创建XService。”
Red Flags - STOP and Reconsider
危险信号——立即停止并重新考虑
If you notice ANY of these, you're about to violate SRP:
- Adding a method unrelated to the class's core purpose
- Class file exceeds 200 lines
- Class has more than 5-7 public methods
- You need section comments to navigate the class
- Multiple developers would edit this class for unrelated features
- Class name contains "Manager", "Handler", "Processor", "Service" with no specific domain
All of these mean: Split the class.
如果你注意到以下任何一种情况,说明你即将违反SRP:
- 添加与类核心用途无关的方法
- 类文件超过200行
- 类有5-7个以上的公共方法
- 需要用分段注释来导航类的内容
- 多个开发人员会因不相关的功能修改这个类
- 类名包含“Manager”“Handler”“Processor”“Service”但没有具体领域限定
出现以上任何一种情况都意味着:拆分这个类。
Refactoring Existing Violations
重构现有违规代码
When you encounter an existing god class:
- Don't make it worse - Never add more responsibilities
- Extract on touch - When modifying, extract the part you're touching
- Document debt - If you can't refactor now, create a ticket
typescript
// Found: OrderService with 500 lines handling orders, payments, inventory, emails
// ❌ WRONG: Add shipping logic to OrderService
// ✅ RIGHT: Create ShippingService, note that OrderService needs refactoring当你遇到一个全能类时:
- 不要雪上加霜 - 绝不要添加更多职责
- 触达即提取 - 修改时,提取你正在处理的部分
- 记录债务 - 如果现在无法重构,创建一个工单
typescript
// 现状:OrderService有500行代码,处理订单、支付、库存、邮件
// ❌ 错误:向OrderService添加物流逻辑
// ✅ 正确:创建ShippingService,记录OrderService需要重构Common Rationalizations (All Invalid)
常见借口(全不成立)
| 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. |
| 借口 | 真相 |
|---|---|
| “放在一个类里更快” | 并没有。两种方式敲的代码量一样。 |
| “小类是过度设计” | 小类是正确的工程设计。 |
| “只是多一个方法而已” | 全能类都是这么开始的。每次都是。 |
| “我们以后可以重构” | 你们不会的。技术债务会不断累积。 |
| “这个类已经很大了” | 这是停止的理由,不是继续的理由。 |
| “这是相关功能” | 相关≠同一职责。 |
| “分段注释有助于导航” | 如果需要导航,说明类太大了。 |
Quick Reference
速查表
| 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 |
| 症状 | 行动 |
|---|---|
| 类做X和Y | 拆分为XService和YService |
| 添加不相关方法 | 创建新类 |
| 文件超过200行 | 寻找提取机会 |
| 多个变更理由 | 一个理由对应一个类 |
| 类名是“Manager/Handler/Processor” | 更具体命名或拆分 |
The Bottom Line
核心结论
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.
一个类。一个职责。一个变更理由。
当迫于压力要违反这一原则时:提出反对、记录情况,或者无论如何都创建正确的结构。
无论时间压力、现有代码情况或权威要求如何,全能类永远不是解决方案。