用途
单一职责原则(Single Responsibility Principle,SRP)用于指导类、模块和函数的设计与修改。其核心定义是:一个类应该只有一个引起变化的原因。每个模块、类或函数只应负责功能中的某一部分。如果你能用“AND”(并且)来描述一个类做了什么,那它就承担了过多职责。
该技能适用于以下场景:
- 创建任何新的类、模块或服务
- 向现有类添加方法
- 审查“做了多件事”的代码
- 感到有压力想“就加在这里吧”的时候
主要能力
铁律
绝不添加会引入第二个变化原因的功能。没有例外:不因“这样更快”,不因“只是多一个方法”,不因“重构太费时间”,不因“技术负责人这么说”,不因“已经上线了”。在压力下违反 SRP 仍然是违反 SRP。
检测方法一:“AND”测试
用一句话描述你的类。如果这句话里含有“AND”,就拆分它。
- “处理用户认证” → 单一职责
- “处理认证并且发送邮件” → 两个职责
- “管理订单并且处理支付并且跟踪库存” → 三个职责
检测方法二:变化原因清单
列出这个类可能因何而变。例如一个 UserManager 类同时包含 login(认证逻辑变化)、updateProfile(资料需求变化)、sendEmail(邮件服务商变化)、trackAnalytics(分析需求变化),就有四个变化原因,应拆分为 AuthService、ProfileService、NotificationService、AnalyticsService。
压力抵抗协议
- 时间压力(“快点让它跑起来”):创建上帝类和创建专注的类耗时相同,“快速”方案产生的技术债日后代价高十倍。行动:创建独立的类,并不会更慢。
- 沉没成本压力(“类已经存在了,直接加进去”):往臃肿的类里加东西只会更糟,已经错了不构成让它更错的理由。行动:创建新的专注类,时间允许时重构现有类。
- 权威压力(“技术负责人说都放一个类里”):礼貌地用证据反驳;若被否决,记录你的顾虑并遵从,但绝不默默创建上帝类。可用的沟通话术是说明拆分理由、不拆的后果,并询问是拆分还是记为技术债。
- 范围蔓延(“既然你在改,顺便加上 X”):新功能等于新类(或已有的合适类)。行动:“X 属于它自己的服务,我会创建 XService。”
危险信号
出现以下任一情况,说明你即将违反 SRP,应停下来重新考虑:
- 添加与类核心目的无关的方法
- 类文件超过 200 行
- 类有超过 5 到 7 个公共方法
- 需要分节注释才能浏览这个类
- 多个开发者会为不相关的功能修改这个类
- 类名包含 Manager、Handler、Processor、Service 却没有具体领域含义
以上都意味着:拆分这个类。
重构既有违规
遇到已有的上帝类时:不要让它更糟,绝不添加更多职责;触碰时抽取,修改时把正在触碰的部分抽出来;记录债务,如果现在无法重构就建一个工单。例如发现一个 500 行、处理订单、支付、库存、邮件的 OrderService,错误做法是往里加物流逻辑,正确做法是创建 ShippingService,并记录 OrderService 需要重构。
常见借口(均不成立)
- “放一个类里更快” → 并不是,代码量一样。
- “小类是过度设计” → 小类是正确的工程。
- “只是多一个方法” → 上帝类就是这样开始的,每次都如此。
- “以后可以重构” → 你不会的,技术债会累积。
- “这个类已经很大了” → 这是停下来的理由,不是继续的理由。
- “这是相关功能” → 相关不等于同一职责。
- “分节注释有助于浏览” → 如果需要导航,类就太大了。
使用方式
该技能以规则和检查清单的形式提供,可在创建或修改类、模块、函数时对照执行。资料未提供具体的安装命令、代码集成方式或工具调用接口。
适用场景
适用于日常编码中的类设计、代码审查、重构决策,以及面对时间、成本、权威或范围压力时的设计取舍。
限制
资料未提供该技能的具体平台支持、收费方式、性能指标或效果数据。其内容为设计原则与应对策略,不包含自动化检测工具或代码生成能力。