Skip to content

软件设计的哲学(第 2 版)· 全书深度思考

系列:书籍笔记 · 软件设计的哲学目录
姊妹篇:程序员修炼之道 · 全书思考


写在前面

John Ousterhout 在本书中只做一件事:把「降低复杂度」讲透
不同于《程序员修炼之道》的职业习惯全景,本书聚焦模块如何切、接口如何设计、注释与命名如何服务可读性。第 2 版(2021)增补「决定什么重要」、加强与《Clean Code》的对比、强化通用模块等论述。

若你只能记住一句话:Working code isn't enough——能跑只是起点,长期成本在复杂度。


1. 核心命题

1.1 复杂度是主要敌人

复杂度 = 开发者理解修改系统所需的认知负担。症状:

  • 修改需改很多处(变更放大
  • 认知负荷高(认知负荷
  • 不知该改哪(未知未知

成因:依赖模糊;且复杂度增量累积——每次小凑合都加一点。

1.2 战略式编程 vs 战术式编程

战术式战略式
目标尽快让功能跑降低长期复杂度
做法能跑就交差多投 10–20% 设计时间
结果短期快、长期慢前期略慢、后期快

Ousterhout 主张:战略式编程是默认姿态;战术式仅用于明确的一次性原型。


2. 二十二章逻辑链

前半:模块与接口(第 4–11 章)——本书心脏。
中段:注释、命名、一致性(第 12–18 章)——让深模块可被理解
后半:潮流、性能、取舍(第 19–21 章)——不盲从方法论。


3. 深模块:全书最重要概念

深模块 = 接口简单、实现强大。
浅模块 = 接口与实现信息量差不多,调用方仍要懂很多细节。

反模式 classitis:为「每个类都小」而拆碎,接口泛滥,复杂度反而上升。

对比:

深模块浅模块
open(path, flags) 背后处理缓存、权限调用方自己拼五个 setter 再 init()
vtkAlgorithm::Update() 背后整管线调用方逐步调五个 Filter 的内部步骤

设计目标:让常见用法极简,把难藏在实现里(第 8 章:下拉复杂度)。


4. 设计原则与红旗(书末浓缩)

原则(节选)

  • 模块应深
  • 信息隐藏,避免泄漏
  • 不同层不同抽象;相邻层可区分
  • 拉复杂度向下( toward 实现)
  • 通用模块更深
  • 设计两次
  • 注释描述代码不明显之事
  • 命名清晰、一致、可搜

红旗(节选)

  • 浅模块
  • 信息泄漏、临时分解
  • 过度通用、过度专用
  • 重复、依赖链过长
  • 注释解释「做什么」而非「为什么」
  • API 强迫调用方处理本可内部消化的情况

复习时可当 code review 检查表


5. 与 GoF / 设计模式

第 10 章:设计模式应拆解为工具,而非仪式。
模式是手段;若引入模式后接口变复杂、模块变浅,则适得其反。
design-patterns-essence.md 一致:模式是变化点管理,不是类图 KPI。

ljz-design-patterns:GoF 教「常见形状」;Ousterhout 教「深不深」。先判断模块是否深,再谈是否套模式。


6. 与《Clean Code》的分歧(第 2 版明示)

话题OusterhoutClean Code 常见主张
方法长度可为长,若利于深模块与隐藏细节宜短
注释重要,写非显而易见信息部分流派贬低注释

不必站队宗教:深模块 + 好注释 可同时成立。


7. 与 Qt / VTK

  • 深模块QIODevice::read()vtkMapper::Render()——简单入口,复杂实现
  • 浅模块反例:为每个小步骤暴露的 Filter 组合 API,强迫应用层编排
  • 信息隐藏vtkObject 内部 vtkSubjectHelper 管理 observer,外部只 AddObserver
  • 分层:UI(Qt)→ 业务 Session → VTK 渲染;层间抽象应不同(第 7 章)
  • vtkCommand 命名:接口像 Command,语义是回调——深不深看调用方要懂多少,见 VTK 专题

8. 与《程序员修炼之道》的配合

程序员修炼之道软件设计的哲学
DRY、正交信息隐藏、减少重复依赖
曳光弹探需求design it twice 定结构
重构习惯修改既有代码时保持深模块
工具与测试注释、命名、显而易见

务实之道保证你在持续整理;设计哲学告诉你往哪个方向整理


9. 个人启发

  1. 写新类前问:调用方最少需要知道什么? 能否再少?
  2. 代码评审多盯接口,少盯行数迷信
  3. 「能跑」之后留 15% 时间做第二次设计对比
  4. 注释写给六个月后的自己:假设、约束、为何不用另一种做法
  5. 潮流(纯 OOP、TDD 万能、微服务)用第 19 章眼光审视:是否降复杂度?

重点与注意

重点复杂度是唯一主敌;战略式编程是默认心态。
重点深模块(简单接口 + 强实现)是全书轴心;浅模块与 classitis 是头号红旗。
重点信息隐藏下拉复杂度设计两次 是日常最可执行的三板斧。
注意:战术式编程只适用于明确丢弃的原型,不是常态。
注意:模式、OOP、短函数都是工具;判断标准是复杂度升降。
注意:注释不是失败,要写代码看不出的信息。
注意:与《程序员修炼之道》互补:一本管习惯,一本管结构


延伸阅读


文档版本:2026-07-07

基于 VitePress 强力驱动 | 记录技术与生活