一个类只应承担单一职责,否则修改易引发连锁问题;需按数据来源、业务语义、技术能力三大边界划分职责,抽离横切关注点与通用能力,避免职责混杂。

User 类,只要换一种数据库或调整邮件模板,整个类都得动,测试也得重来。
职责划分的核心判断标准
问自己一个问题:如果这个需求下周要改,哪些代码会因此被修改?如果答案涉及多个不相关的功能点,说明职责已经混在一起了。
- 校验逻辑变 → 改
validate(),不该牵扯到sendWelcomeEmail() - 存储方式从 MySQL 换成 Redis → 只该动仓储层,
User实体类本身不应感知 - 注册流程加短信验证码 → 新增一个
SmsVerificationService,而不是往UserController里硬塞一堆 if 分支
常见职责混淆场景与拆分方式
下面这些组合在实际项目里高频出现,但都不该共存于一个类:
-
User类里直接调用mail()或file_put_contents()→ 把通知、日志等横切关注点抽成独立服务,比如EmailNotifier、ActivityLogger -
Order类中包含计算运费、查库存、生成 PDF 发票的全部逻辑 → 运费用ShippingCalculator,库存走InventoryChecker,PDF 交给InvoiceGenerator - 控制器方法里一边查数据库、一边格式化响应、一边写审计日志 → 数据获取归
Repository,格式化归ResponseTransformer,日志归AuditLogger
private/protected/public 不是封装的终点,而是起点
设了 private $email 只是第一步。真正关键的是:所有对它的读写是否都经过可控路径?
- 构造函数里不做校验,靠外部传入合法值 → 错。应调用
$this->setEmail($email),在 setter 中用filter_var($email, FILTER_VALIDATE_EMAIL)检查 - 允许通过反射绕过
private直接改属性 → PHP 7.4+ 的类型声明 +__set()拦截能堵住一部分,但更可靠的是靠设计约束(比如不暴露可写接口) - 子类需要扩展行为,却因父类方法全是
private而被迫复制粘贴逻辑 → 改成protected并留出钩子,比如protected function beforeSave(): void
重构时最容易被忽略的边界
职责划分不是越细越好,过度拆分会让调用链变得冗长难读。重点守住三个真实边界:
- 数据来源边界:HTTP 请求参数、数据库记录、缓存结果、第三方 API 响应 —— 各自有适配器,不混用
- 业务语义边界:「创建用户」和「激活用户」是两个不同用例,即使共享部分字段,也不该塞进同一个方法
- 技术能力边界:加密、序列化、时间处理这些通用能力,必须抽离为工具类或 trait,禁止在业务类里重复实现
hash_hmac()或date('c')
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











