solid原则是判断代码可维护性的经验标尺,而非语法或库;需在开发中下意识评估变更影响范围,识别多职责、硬编码、伪依赖倒置等问题,并以“三次修改”为信号启动重构。

直接学 SOLID 原则本身没有意义——它不是语法,也不是函数库,而是一套判断“代码是否容易改、是否敢动”的经验标尺。你不需要背全五条定义,而是要在写 UserController、PaymentService 或重构一个 800 行的 OrderProcessor 时,能下意识问一句:“这里如果换数据库,要改几处?加个新通知渠道,得动多少类?”
怎么识别一个类违反了单一职责(SRP)
看它有没有多个“不得不改”的理由:数据库字段变了要改它,邮件模板换了要改它,权限规则升级还要改它——这就是典型的 SRP 违反。
- 检查构造函数和方法签名:
__construct( PDO $pdo, Mailer $mailer, Logger $logger )是危险信号,说明它在协调多个基础设施 - 方法名混用动词层级:既有
saveToDatabase(),又有notifyAdmin(),还有generateReportPdf(),三者属于完全不同的业务维度 - 单元测试文件里要 mock 的依赖超过 2 个(比如同时 mock DB、Redis、HTTP client),说明它承担了不该管的事
开闭原则(OCP)落地时最常踩的坑
不是“写了接口就自动 OCP”,而是看新增功能时,是否真没碰旧逻辑的源码。
- 反模式:
switch ($paymentType)在核心处理方法里硬编码 case,每加一种支付方式就得改这个文件 - 正确姿势:定义
interface PaymentGateway,让AlipayGateway、WechatGateway各自实现,调用方只依赖接口,新增类不改已有代码 - 注意 Laravel 的
Event::listen()或 Symfony 的 event subscriber 本质就是 OCP —— 加监听器不改事件触发逻辑,但很多人把它当“钩子”乱用,塞进大量业务判断,反而破坏了可替换性
依赖倒置(DIP)在 PHP 中最容易被忽略的细节
类型提示用了接口,不代表 DIP 就成立了。关键看实例从哪来、怎么绑定。
- 写了
public function __construct(UserRepositoryInterface $repo),但在构造对象时仍手动 new:new UserController(new EloquentUserRepository())—— 接口只是摆设 - 容器绑定错位:把
UserRepositoryInterface::class绑定到FileUserRepository::class,但实际运行环境需要数据库,结果上线才报错 - DTO 或 Entity 当接口用:
public function handle(User $user)看似松耦合,但User是具体类,含属性、构造逻辑、甚至 ORM 方法,违反 DIP;应传UserData或UserInput这类无行为纯数据结构
真正难的不是理解每条原则,而是判断“现在要不要拆”。过早抽象会增加认知负担,过晚重构会让改一处牵八处。最务实的做法是:每次改一个类超过 3 次(比如修 bug、加字段、换日志方式),就停下来问问,是不是该把其中一块拎出去了。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











