单一职责原则的核心是“变化原因唯一”,而非功能数量多少;一个类应仅因一个理由被修改,职责即变化的动因,需依变更场景(如权限规则、日志格式、注册流程)判断是否混杂,接口与实现均须职责一致,但无独立变化迹象时不必过度拆分。
单一职责原则(SRP)在类功能划分中的界定标准,核心不在于“功能数量多少”,而在于“变化原因是否唯一”。一个类是否符合SRP,关键看:当需求或环境发生变化时,有没有且仅有一个理由需要修改它。
职责 = 变化的原因,不是功能的罗列比如一个UserManager类包含创建用户、校验权限、写操作日志三个方法。表面看是三件事,但需追问:如果权限规则调整(如从角色制改为RBAC),哪些方法要改?——只有校验逻辑如果日志格式升级(如增加traceId字段),哪些方法要改?——只有日志写入部分如果用户注册流程新增实名认证步骤,哪些方法要改?——主要是创建逻辑三类修改动因彼此独立,说明这三个功能属于三个不同职责轴,不应共存于同一个类中。
判断是否该拆分的实操信号以下情况强烈提示职责混杂,需考虑分离:类中出现明显不同领域的名词:如同时含“log”、“auth”、“export”、“notify”
等前缀的方法不同方法由不同团队维护或按不同节奏迭代(如日志模块每季度升级,用户主流程每月发版)
单元测试用例明显分组:一组测业务逻辑,一组测格式转换,一组测外部调用添加新功能时,常需在多个已有方法里插入相似代码(如每次都要加埋点或审计日志)
接口与实现层的职责一致性SRP 不只约束类,也约束接口定义。例如:❌ 违反 SRP 的接口:public interface UserService {void createUser(User user);List
不必过度拆分的边界条件SRP 不是越细越好。以下情形可保留在同一类中:两个行为始终同步变更(如用户id和username字段永远由同一份业务规则约束)
技术约束使分离成本远高于收益(如硬件驱动中连接控制与数据收发物理上无法解耦)
当前无任何迹象表明二者会独立变化(没有历史变更记录,也没有明确的演进路线图)
此时强行拆分反而引入不必要的抽象和间接层。
