mcpField
S
single-responsibility-principle

single-responsibility-principle

github.com/yanko-belov开发1348 次安装40 周前更新
代码仓库

关于 single-responsibility-principle

single-responsibility-principle 是一项编程技能,指导开发者让每个类、模块或函数只承担一项职责,并识别何时应拆分功能,避免加入无关职责。

主要功能

  1. 01遵循单一职责规则
  2. 02识别多个变更原因
  3. 03发现过大的类的迹象
  4. 04提取职责明确的组件

适用场景

  1. 01设计新类或新模块
  2. 02审查含无关方法的类
  3. 03重构已有的臃肿类

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/yanko-belov/code-craft --skill single-responsibility-principle

安装后在 Claude Code 中输入/single-responsibility-principle确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

user-system/
AnalyticsService.ts
AuthenticationService.ts
index.ts
NotificationService.ts
ProfileService.ts

详细介绍

单一职责原则(SRP)

概述

一个类应该只有一个变更理由。

每个模块、类或函数都应该只负责一项功能。 如果你需要用“并且”来描述一个类的职责,那它承担的职责就太多了。

适用场景

  • 创建任何新类、模块或服务
  • 向现有类添加方法
  • 审查“做多件事”的代码
  • 感觉自己忍不住想“就加在这里吧”

铁律

NEVER add functionality that introduces a second reason to change.

绝无例外:

  • 不能因为“这样更快”
  • 不能因为“只多加一个方法”
  • 不能因为“重构要花太长时间”
  • 不能因为“我的技术负责人这么说”
  • 不能因为“它已经上线了”

在压力下违反 SRP,依然是在违反 SRP。

检测: “并且”测试

用一句话描述你的类。如果其中包含“并且”,就拆分它。

描述判定
“处理用户身份验证”✅ 单一职责
“处理身份验证并发送电子邮件”❌ 两项职责
“管理订单并处理付款,还跟踪库存”❌ 三项职责

检测:变更理由

列出这个类可能需要变更的原因:

// ❌ 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() {} }

抗压应对流程

当有人施压要求违反 SRP 时,请按以下方式处理:

1. 时间压力

“先快速让它能用”

回应: 创建一个上帝类,耗时并不比创建职责明确的类少。这个“快速”方案会造成技术债,日后代价可能高出 10 倍。

行动: 创建独立的类。并不会更慢。

2. 沉没成本压力

“这个类已经存在了,直接加进去就行”

回应: 往臃肿的类里添加内容,只会让它更糟。它已经有问题,不代表可以让问题变得更严重。

行动: 创建一个职责明确的新类。如果时间允许,再重构现有类。

3. 权威压力

“我的技术负责人说把所有内容都放在一个类里”

回应: 以证据为依据,礼貌地提出异议。如果对方仍坚持,就记录你的顾虑并照做,但绝不要默默创建上帝类。

行动:

"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. 范围蔓延

“既然你已经在改这里,也顺便加上 X”

回应: 新功能 = 新类(或已有的合适类)。

行动: “X 应该属于独立的服务。我会创建 XService。”

危险信号 - 停下并重新考虑

如果你注意到以下任意情况,说明你正要违反 SRP:

  • 添加与类核心用途无关的方法
  • 类文件超过 200 行
  • 类有超过 5-7 个公共方法
  • 你需要用分节注释才能浏览这个类
  • 多位开发者会因互不相关的功能而修改这个类
  • 类名包含“Manager”、“Handler”、“Processor”或“Service”,但没有具体的领域限定

这些情况都意味着:拆分类。

重构现有违规代码

遇到现有的上帝类时:

  1. 不要让情况更糟 - 绝不要添加更多职责
  2. 修改时顺手拆分 - 修改时,拆出你正在处理的部分
  3. 记录技术债 - 如果现在无法重构,就创建一个工单
// Found: OrderService with 500 lines handling orders, payments, inventory, emails

// ❌ WRONG: Add shipping logic to OrderService
// ✅ RIGHT: Create ShippingService, note that OrderService needs refactoring

常见的自我辩解(都不成立)

借口事实
“放在一个类里更快”并非如此。无论哪种方式,输入的代码都一样。
“小类属于过度设计”小类才是正确的工程实践。
“只多加一个方法”上帝类每次都是这样开始的。
“以后可以重构”你不会重构。技术债会不断累积。
“这个类已经很大了”这正是应该停下的理由,而不是继续的理由。
“这些功能相关”相关 ≠ 相同职责。
“分节注释有助于浏览”如果需要导航,说明类太大了。

快速参考

症状操作
一个类执行 X 和 Y拆分为 XService 和 YService
添加无关方法创建新类
文件超过 200 行寻找拆分机会
有多个修改原因每个原因对应一个类
名称中含有“Manager/Handler/Processor”使用更具体的名称或拆分类

归根结底

一个类。一项职责。一个修改原因。

当有人施压要求违反这一原则时:提出异议、记录情况,或仍然创建合理的结构。

无论时间压力、现有代码还是权威要求如何,巨型类都不是答案。

评论

支持 Markdown