SOLID 再探 — 后模式视角
Source: Dev.to
为什么原则本身不如背后的力量重要
SOLID 不是一个检查清单。
它是对更深层力量的历史性压缩。
这是系列的 第 5 部分:
- C# 中的类:从第一原理到架构精通
- 抽象类 vs 接口 — 系统视角
- 组合 vs 继承 — 变化的物理学
- 封装与信息隐藏 — 为无知而设计
- SOLID 再探 — 后模式视角
本文假设你已经 了解 SOLID。
我们的目标是理解 它为何存在、何时会失效,以及 当模式消退时仍然保留的东西。
将 SOLID 作为规则进行教学的问题
大多数开发者把 SOLID 当作五条独立的戒律来学习:
- 单一职责
- 开放/封闭
- 里氏替换
- 接口分离
- 依赖倒置
它们的教学方式是:
- 静态规则
- 本地代码检查
- 重构启发式
但 SOLID 本意并非如此使用。
SOLID 是对 在变化中的系统的涌现描述。
SOLID 关注的是变化,而非代码
每条 SOLID 原则的存在都是为了解答一个问题:
“变化落在哪里——它会传播多远?”
SOLID 并不是关于美观。
它关注的是 损害控制.
S — Single Responsibility Principle
(实际上:Single Reason to Change)
SRP 并不是关于“类要小”。
它是关于 分离变更的理由。
public class ReportService
{
public void Generate() { }
public void SaveToDisk() { }
public void SendEmail() { }
}
这个类只有一个职责(报告),但 有三个变更理由。
当 组织边界 重叠时,SRP 被违反。
它关注的是 谁 提出变更,而不是 类有多大。
O — 开放/封闭原则
(在无需协作的情况下进行扩展的设计)
OCP 的存在是为了降低 协作成本。
public interface IDiscountPolicy
{
decimal Apply(decimal price);
}
新行为以 新代码 的形式出现,而不是修改已有代码。
真正的好处:
- 没有会议
- 没有合并冲突
- 不用担心破坏他人代码
OCP 是一种 社会规模化原则。
L — 里氏替换原则
(防止语义漂移)
LSP 并不是关于继承语法。
它关注 意义保持。
Stream s = new MemoryStream();
这能正常工作,因为:
- 期望仍然有效
- 语义得到保留
如果行为让调用者感到意外,LSP 就被破坏了——即使编译器没有报错。
LSP 保护抽象中的 信任。
I — 接口隔离原则
(最小化认知负荷)
ISP 存在是因为 人类是瓶颈。
public interface IWorker
{
void Work();
void Eat();
}
并非所有工作者都吃饭。
ISP 被违反的情况有:
- 实现者被迫关注他们不需要的东西
- 理解时需要阅读无关的方法
ISP 优化的是 思维带宽,而非运行时。
D — 依赖倒置原则
(颠倒易变性的流向)
DIP 是 SOLID 的 基石。
高级策略不应依赖低级细节。
public class OrderService
{
public OrderService(IPaymentGateway gateway) { }
}
依赖的方向被颠倒:
- 稳定的代码依赖于稳定的抽象
- 易变的代码挂在边缘
DIP 旨在 保护核心。
SOLID 作为力量图
| Principle | Primary Force Controlled |
|---|---|
| SRP | 组织变革 |
| OCP | 协同成本 |
| LSP | 语义稳定性 |
| ISP | 认知负荷 |
| DIP | 波动方向 |
当这些力量重要时,SOLID 起作用。
当 SOLID 变得有害
SOLID 在以下情况下失效:
- 机械式应用
- 过早强制执行
- 局部优化而非系统性优化
典型症状:
- 每类接口爆炸
- 领域过度抽象
- “因为 SOLID 这么说” 的代码
这就是 cargo‑cult architecture.
后模式思考
模式和原则是 地图,而不是领土。
在成熟的系统中:
- 约束比模式更重要
- 力量比规则更重要
- 演化比优雅更重要
SOLID 逐渐淡出视野——剩下的是 有意的设计。
统一的思维模型
SOLID 最小化变更的影响范围。
如果一个设计能够减少:
- 爆炸半径
- 协调
- 意外
- 恐惧
它就是 SOLID —— 即使它违反了教材规则。
最终要点
初级开发者会问:
“这符合 SOLID 吗?”
高级工程师会问:
“当它改变时会怎样?”
那个问题包含了全部五个原则。
✍️ Cristian Sifuentes
.NET / C# • Architecture • Systems Thinking
原则并不能扩展系统,理解驱动力才行。