修改代码的艺术
No related notes
Outlinks (0)
No outlinks found
Backlinks (0)
No backlinks found
1 · 读书笔记:修改代码的艺术
Working Effectively with Legacy Code
一句话:教你如何在没有测试的遗留代码中安全地打破依赖、补上测试、自信地修改——而不是推倒重写。
- 是什么(What)— 遗留代码 = 没有测试的代码;缝(Seam)= 不改源码就能替换行为的位置,本质是代码中的可替换点(而非分隔点);特征测试 = 锁定现有行为而非期望行为的测试
- 为什么(Why)— 重写风险高、成本大,渐进式改造才是现实选择;没有测试就无法自信修改,而依赖是写不了测试的根本原因
- 怎么做(How)— 找接缝 → 打破依赖(提取接口/子类化重写/参数化构造函数)→ 写特征测试锁定行为 → 小步修改;用草稿重构理解代码,用影响草图控制波及范围
1.1 · 核心观点:
遗留代码 = 没有测试的代码。修改遗留代码的核心循环是:找到变更点 → 找到测试点 → 打破依赖 → 写测试 → 修改。安全地修改代码的前提不是”理解全部”,而是”能用测试保护你要动的那一小块”。
遗留代码 = 没有测试的代码(没有测试就不敢改)。解法是逐步增加测试:找到缝(代码中已有的、不修改源码就能替换行为的位置)→ 制造缝(通过最小的结构性重构如提取接口来创造可替换点)→ 使用缝(注入测试替身,开始写测试)。测试什么?用特征测试记录当前行为——不需要完全理解代码,先把”它现在是怎样的”锁定下来,然后在这个安全网上增量覆盖修改后的新行为。
1.2 · 启发点(关键洞察):
- 遗留代码的定义与心态(What/Why)— 遗留代码不是”老代码”,而是”没有测试覆盖、无法自信修改的代码”。这个定义把问题从”代码年龄”转移到”可修改性”,改变了我们对待旧代码的态度:不是重写,而是逐步驯化。
- 接缝(Seam)是打破依赖的关键抽象(What/How)— 接缝是程序中”不用修改源码就能改变行为”的位置。三种接缝:预处理接缝、链接接缝、对象接缝。找到接缝就能注入测试替身,让不可测代码变得可测。这是全书最核心的技术概念。
- “先写测试再改代码”的悖论与破解(Why/How)— 要安全修改代码需要测试,但要写测试又需要先修改代码(打破依赖)。解法:允许做最小的、保守的结构性重构(如提取接口、参数化构造函数)来引入接缝,这些重构风险极低,可以不需要测试保护。
- Characterization Test(特征测试)(How)— 不是验证”代码应该怎样”,而是记录”代码现在怎样”。先观察当前行为,再把它锁定为测试。这让你在不理解全部逻辑的情况下也能安全修改。
- Scratch Refactoring(草稿重构)(How)— 当代码太复杂无法理解时,大胆地重构它来理解结构,然后丢弃所有修改。目的不是改代码,而是建立理解。这是一种低风险的学习手段。
- 修改代码的四个理由(What)— 添加功能、修复 Bug、改善设计、优化性能。每种理由下变与不变的部分不同,清楚区分能帮助你控制修改范围。
- “编辑并祈祷” vs “覆盖并修改”(Why)— 前者是没有测试时的常见做法:小心翼翼地改,然后祈祷没出错。后者是用测试覆盖住要改的区域,然后自信地修改。两种方式的心理负担和风险完全不同。
- 效果的传播与影响分析(How)— 修改一个变量/方法后,影响会沿着数据流和调用链传播。画出”影响草图(effect sketch)“能帮你确定最小测试范围,避免”改一处崩十处”。
1.3 · 行动:
- 面对遗留代码时,先问”接缝在哪里”,用提取接口、子类化并重写、参数化构造函数等手法打破依赖,再补特征测试
- 对看不懂的代码做草稿重构:放心大胆地改,理解后
git checkout丢掉,再用正式流程修改 - 每次修改前画影响草图,明确”我这次改动会波及哪些路径”,用测试覆盖这些路径
1.4 · 金句:
- “Legacy code is simply code without tests.”
- “A seam is a place where you can alter behavior in your program without editing in that place.”
- “When we have tests, we can make changes with confidence. Without them, we just don’t know.”
- “Dependency is one of the most critical problems in software development. Much of the work in getting legacy code under test involves breaking dependencies.”
- “Programming is the art of doing one thing at a time.”