Skip to content

第 10 章:从设计上消灭错误

系列:软件设计的哲学 · 第 10/22 章
全书导读:00-overview.md


一句话总结

优先从定义上消除错误类(让非法状态难表示),而非用异常和 if 在运行时到处救火。


核心观点浓缩

  • 定义消除:收窄类型、合并操作、设合理默认值,使错误无法构造
  • 异常应用于真正罕见、调用方难以预防的情况
  • 过多异常分支 = 复杂度上浮,与第 8 章下拉原则相悖
  • 设计模式是工具箱,非仪式;若模式让接口更复杂,应拆掉而非套用
  • 好 API 让正确用法显眼,错误用法在编译期或第一次调用就失败

关键概念 / 金句

策略示例
定义消除ClosedFile / OpenFile 类型,而非 isOpen 标志
合并操作原子 transfer(from, to, amount) 而非分步扣款
例外用异常磁盘满、网络中断——调用方无法设计消除

本章在全书中的位置

第 10 章把模块设计延伸到契约与错误模型,衔接第 11 章设计过程。也回应「模式崇拜」:GoF 解法应拆解为降低复杂度的具体手法。


个人思考与启发

扫描状态机若用裸 int phase + 各处校验,错误分散。改为 enum class Phase 且仅在合法转移函数内变更,非法转移在 API 层不可表达,调试面大幅缩小。


与《程序员修炼之道》对照

  • 契约式设计(前置/后置条件)与定义消除同源:约束写清楚,错误早发现
  • 「死程序不说谎」:崩溃优于静默错误;本书更进:别让错误可写进代码
  • 断言用于不可能分支;业务可恢复错误用结果类型——分工与本书一致

重点与注意

重点:先问「能否让这类错误不存在?」再问「捕获后怎么办?」
重点:模式引入前做复杂度会计:接口变简单还是变啰嗦?
注意:定义消除过头会类爆炸,用合理默认值平衡。
注意:用户输入错误无法消灭,应下拉到模块内转成安全结果,非抛给 UI 判 20 种码。


导航第 9 章 拆还是合 · 下一篇:第 11 章 设计两次

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