设计模式六大原则

52 阅读4分钟

一、先说动机:为什么需要这些原则?

软件的主旋律是“变化”。每一次需求/技术/合规变化,都会在代码图上引发“涟漪效应”(改动一处牵扯多处)。六大原则就是行业长期实践中对“降低涟漪成本”的经验压缩,其共识目标是:

  • 降低修改半径(局部化变化)

  • 降低依赖强度(把握依赖方向)

  • 保持替换安全(多态不踩雷)

  • 控制接口边界(暴露越少越好)

  • 提升可测试性与可演进性

换句话说:设计 = 管理变化,六大原则分别从“职责、扩展、替换、依赖、接口、协作”六个轴来约束变化的代价。


二、六个轴分别解决什么问题?

原则关注对象解决的核心问题一句话检验
SRP 单一职责模块/类让变化有且仅有一个原因触发它“这个类改动的理由能不能再分?”
OCP 开闭扩展点新需求尽量新增代码而非改旧码“这类变化能用新增实现吗?”
LSP 里氏替换类型层次子类型可替换父类型且不破坏正确性“把子类实参换成父类,行为还对吗?”
DIP 依赖倒置依赖方向高层不依赖低层细节,共同依赖抽象“稳定层是否只依赖抽象/接口?”
ISP 接口隔离API 形状客户只看到/实现自己需要的方法“这个接口对某个客户是否‘太胖’?”
LoD 迪米特法则协作半径降低对象间了解度,减少链式耦合“我是否在跟‘朋友的朋友’说话?”

直觉图:

  • SRP管“内聚”;

  • OCP/DIP/ISP共同管“扩展与依赖方向”;

  • LSP是“多态正确性”的约束;

  • LoD管“耦合半径”(信息隐藏)。


三、它们之间不是平行孤岛,而是“内在联动”

  • OCP 的落地往往依赖 DIP(抽象扩展点)+ ISP(细粒度接口)+ LSP(替换安全)。

  • SRP提升内聚,间接降低因修改引起的连锁反应,为 OCP 创造土壤。

  • LoD限制“对象图的触达距离”,避免“修改 A 却牵连 A 的朋友们”,与 SRP 一起控制耦合扩散。

因此,“正好这六个”的原因是:它们覆盖了从类型正确性到依赖方向、到接口边界、到协作半径的关键面,彼此配合构成一个相对闭合的“变化成本最小化”体系。


四、用小例子看每条原则的“痛点—解法—收益”

  1. SRP:报表服务既算账又发邮件 → 拆成 ReportGenerator 与 Notifier。

    • 变化:改邮件模板不再触动计算逻辑。
  2. OCP:新增一种“积分优惠” → 通过注册新的 DiscountPolicy 实现,而非改 switch。

  3. LSP:Square 继承 Rectangle 导致 setWidth 破坏长方形不变量 → 抽象为 Shape,分别实现面积逻辑,避免错误替换。

  4. DIP:高层模块依赖 PaymentGateway 接口,具体用 Stripe/PayPal 由装配期决定。

  5. ISP:把“超大通用 DAO 接口”按读/写/分页拆成小接口,调用方只依赖所需能力。

  6. LoD:拒绝 order.getCustomer().getAddress().getCity() 的链式穿透,改成 order.city() 由内部转发(或一次性 DTO)。


五、为什么不是更多或更少?

  • 少了不够用:只讲 SOLID(SRP/OCP/LSP/ISP/DIP)还少一个“协作半径”的视角,于是补上 LoD,能更好控制对象图的传播耦合。
  • 多了冗余/重叠:再继续加(如“合成复用原则”CARP),常与前述在工程实践中功能重叠(组合优先本质也服务于 SRP/OCP/DIP/LoD)。六条已能覆盖主流变化维度,保持“简洁而不简单”。

六、应用取舍:别教条,讲“触发器”

  • **何时启用/加强?**出现以下 smell 就该引入对应原则的重构:

    • “上帝类/巨类” → SRP 拆分;
    • 新需求总要改旧类 → 抽象扩展点(OCP + DIP + ISP);
    • 子类替换父类出错/需要写 instanceof → LSP 改抽象或去继承用组合;
    • 方法调用出现“火车式点号”→ LoD 封装转发;
  • 何时克制?过度抽象、接口碎片化、为未来而设计都会增加即时复杂度。经验法则:先直白实现 + 用测试保护,当出现第二次相似变化时再抽象成可扩展形。


七、落地清单(面向团队评审/自检)

  • 每个类是否能一句话说清“唯一职责”?(SRP)
  • 新增一种策略/适配器时是否无需改旧类?(OCP)
  • 任何使用父类型的地方换子类型是否毫无意外?(LSP)
  • 依赖是否都指向接口/抽象,具体实现由装配期决定?(DIP)
  • 接口是否细到“客户只依赖需要的方法”?(ISP)
  • 代码中是否存在“朋友的朋友”式长链访问?(LoD)

一句话总结

六大原则是围绕“最小化变化成本”从六个正交维度提炼出的行业共识:用 SRP 提高内聚、以 OCP/DIP/ISP 打造可扩展与正确的依赖方向、凭 LSP 保证多态替换安全、再用 LoD 控制协作半径。它们彼此支撑,构成一个能让系统易改、易测、易演进的最小充分集合。