0. 当 AI 成为“编码搭子”的那一刻
早上九点,当你打开 IDE,随手敲出一段“今日任务”后,一边优雅地享用咖啡一边等待 AI 为你完成编码工作。 当你看到代码以肉眼可见的速度铺满屏幕时,你不禁想凡尔赛一下:“AI编程的快乐往往就是这么朴实无华,且枯燥”。 然而好景不长,当 prompt 的效果逐渐减弱,生成的代码频繁出错时,你不得不亲自出马修复功能, 却发现职责混淆、链式依赖、冗余逻辑迎头扑来,一瞬间仿佛回到从前那座“屎山”项目里:每修一处,又冒出三处新的坑。 更棘手的是,AI 上下文窗口有限,往往只看得见文件的冰山一角,遇到跨模块调用或深层继承链,立刻陷入“生成→报错→再生成→再报错”的无限循环。
这种“快感”与“焦虑”并存的体验,让我们不得不重新审视:在 AI 辅助编程时代,哪些设计准则依旧是守护代码质量的灯塔?又该如何调整设计思路才能发挥 AI 最佳效能?
1. 传统面向对象设计六项原则回顾
在函数式浪潮大规模来袭之前,Uncle Bob 提出的 SOLID 原则,加上迪米特法则,曾是面向对象(OO)设计的绝对标配, 为高内聚、低耦合的软件设计与系统演化提供了明确指导。
- 单一职责 (SRP): 一个类只干一件事,只因一个理由改动,维护成本自然不飙升。
- 开闭原则 (OCP): 对扩展友好,对改动说“不”,新增功能塞进新类就好。
- 里氏替换 (LSP): 子类型严格遵守契约,得能无缝替换父类型。
- 接口分离 (ISP): 把大而全的接口拆成小而专,小粒度更灵活。
- 依赖倒转 (DIP): 高层、低层都得靠抽象,不跟具体实现打交道。
- 迪米特法则 (LoD): 只跟直系朋友通信,别随意链式调用,信息隐藏更内聚。
这些原则诞生于 25 年前的 OOP 黄金时代。那时,Java、C++ 等语言携带着OO特性牢牢把控着开发范式的话语权。 可当函数式特性流入主流语言,声明式 UI 崛起,纯函数、组合、单向数据流成了新宠,SOLID 原则也被“新时代”逐步分解、重构。
2. 面向现代开发实践的新六项原则
为了更好地适应现代开发实践,在尊重传统的基础上,我做了点“轻度改造”,保留跨范式依旧有效的核心,替换掉被函数式、声明式天然覆盖或弱化的部分:
| 新六项原则 | 核心思路 |
|---|---|
| 单一职责 (SRP) | 模块要小而专,复杂度易控 |
| 开闭原则 (OCP) | 插件化扩展,无需动旧代码 |
| 组合优于继承 (Composition over Inheritance) | 用小组件/函数拼出大功能 |
| 消除副作用 (Side‑Effect Elimination) | 函数严守契约(签名),放心使用 |
| 数据驱动 (Data‑Driven) | 不同层级间都依赖于数据,状态可追踪 |
| 深模块原则 (Modules Should Be Deep) | 接口极简、实现极深,隐藏细节 |
注: 深模块原则(Modules Should Be Deep) 由John Ousterhout在他的《A Philosophy of Software Design / 软件设计的哲学》一书中提出。
新旧原则间基本上是同生态位的替换关系,详见下图:
下面用一些例子来解释下新增的四项原则:
- 组合优于继承 (CoI): 在游戏中,通过将
CanFly、CanShoot等能力接口组合到实体上,而不使用深层继承树来实现各类敌人。 - 消除副作用 (SEE): 在函数式编程中,
map、filter等操作符仅依赖输入数据,返回新数据而不修改原数据。 - 数据驱动 (DD): 在 React 中,组件通过
props接收数据并渲染视图,任何 UI 变化都由state或props推动,而非手动操作 DOM 或组件实例属性。 - 深模块原则 (MSBD): 在 UNIX 中, I/O 模块仅有
open/read/write/close等接口,却支持缓冲、权限、异步等复杂特性,是符合该项原则的典范。
3. 新六项原则在 AI 辅助编程时代的适用性
目前大多数 AI 编程助手,还撑不起独立思考:记不住全局上下文,看不明复杂关系。最佳实践依旧是——人类定架构,AI 填细节。 在这种前提下,分治思想和模块契约变得格外重要,遵循这一原则让我逐一分析一下新六项原则:
| 原则 | 适用性 | 理由 |
|---|---|---|
| 单一职责 (SRP) | ⭐⭐⭐⭐⭐ | 小模块更易在有限上下文里被 AI 理解,减少“黑盒”惊吓 |
| 开闭原则 (OCP) | ⭐⭐⭐☆☆ | 扩展设计仍靠人脑把关,AI 可按契约新增实现,但不擅长全局重构 |
| 组合优于继承 (CoI) | ⭐⭐⭐⭐☆ | 组件/函数拼装直观灵活,AI 生成代码时不易踩继承坑 |
| 消除副作用 (SEE) | ⭐⭐⭐⭐⭐ | 纯函数最易调试和测试,AI 只管输入输出,别让它管全局状态 |
| 数据驱动 (DD) | ⭐⭐⭐⭐⭐ | 单向流与明确数据契约,AI 可专注数据转化,无需追踪隐式状态 |
| 深模块原则 (MSBD) | ⭐⭐☆☆☆ | 简洁接口保护实现细节,但 AI 也难窥全貌,问题定位不够直接 |
用图来描述会更加直观,如下图所示,越靠近左下角的原则与 AI 的适配性越高。
综上所述,单一职责 (SRP)、消除副作用 (SEE)、数据驱动 (DD) 是 AI 时代的三驾马车—— 足够小、足够纯、足够规范,最适合“AI 填细节”的场景。
实践建议: 早期写好 README,把架构图、模块职责都写清楚;准备一份“编码示例”文档,让 AI 按照“契约”写代码,出错率会直线下降。
4. 总结
AI 无法替代对架构的把控,也甩不掉对契约的坚守。要让人机协作高效,你可以这么做:
- 设计阶段:写清 README、契约文档、架构图。
- 编码阶段:坚持纯函数、小模块、数据驱动。
- Prompt 阶段:提供示例代码,让 AI 读懂你的风格。
只需要在宏观上遵守 开闭原则 (OCP)、组合优于继承 (CoI)、深模块原则 (MSBD), 在微观上遵循 单一职责 (SRP)、消除副作用 (SEE) 和 数据驱动 (DD), 再由人类来定大局,AI 来刷细节,就能实现高效、可维护、可演化的新常态。 希望这份轻量级原则,能让你和 AI 携手写出更精致的“代码乐高”。