在 AI 时代,代码不再需要“经历岁月”才会变成遗留代码,它可以在生成的瞬间就成为遗留代码。
笔者最近在重构一些模块,重新翻出 Michael Feathers 的《Working Effectively with Legacy Code》读了一遍。感触比第一次读时更深。

Table of Contents
1 AI Coding 时代的遗留代码
Feathers 书中对遗留代码的定义:没有测试的代码就是遗留代码。
没想到在 AI Coding 时代,这个定义不但没过时,反而扩大了……
1.1 遗留代码的边界在扩大
传统遗留代码 = 前辈写的、文档丢了的、没人敢碰的代码。AI 时代多了几个新品种:
- 你自己几个月前写的代码 —— 上下文忘干净了,等于别人写的。
- AI agent 生成、你 review 过的代码 —— review 的时候觉得没问题,但深度未必覆盖了所有分支和边界。
- AI 写完你又改了两行的代码 —— 危险。人机混编,两边的心智模型和理解都不完整。
共同特征:测试覆盖不足+上下文不足。按 Feathers 的标准,现在看这些全是遗留代码。
这就是笔者最近明显感受到的:代码不再需要"经历岁月"才变成遗留代码——它可以在生成的那一刻就成为遗留代码。
1.2 人类变成 supervisor,经典反模式就是 review checklist
Agent 写代码越来越多,人类开发者的重心从"写"迁移到了"看"和"编排"。顶层架构设计、模块边界划分、接口契约——这些决策 agent 做不了,得人来负责。
那人类 review 的时候到底在看什么?笔者发现一个重点就是在查反模式、在闻代码的坏味道。
WELC 全书讲的那些"改不动代码"的结构性问题——巨型方法、上帝类、隐藏的全局依赖、无法脱离运行环境测试的模块——放到今天,恰恰是人类 review agent 提交的代码时该盯着看的清单。
现在大伙探索的 harness engineering 也将对抗熵增作为重点事项。经典书籍已经给了成熟的识别模式和处理手法。没想到在 20 年后的今天,人类角色变了,这些东西竟然突然变成了 supervisor 的刚需。
博主在 review agent 提交的模块时会问自己两个问题:
- 如果后续要重构这个模块,现有的单元测试能不能高信心覆盖?
- 这个模块的耦合程度,允不允许我把它单独拎出来重构?
答案是否定的,当场就得让 agent 补测试、解耦合。不要留到以后。
1.3 写测试的成本已经低到没有借口力!
过去写单元测试是体力活,团队永远在"赶功能"和"补测试"之间拉扯。别说几百个 case 了,光十几个 case 和对应的插桩 mock 操作,写到最后真的是纯纯红温。
Agent 时代这个矛盾基本消解了——逻辑分支全覆盖、边界条件穷举、mock 对象批量生成,agent 几分钟搞定人类写一下午的活。
Feathers 的核心工作流:先写测试,再改代码。 二十年了,方法论没变,变的是执行成本——现在几乎为零。
真的,不要吝啬。让 agent 默认按"这个模块后续随时可能被重构"的前提,生成高强度的特征测试。
2 AI 时代重构遗留模块的工作流
结合 WELC 的思路和 agent 的能力,博主摸索出一套实践流程。
第一步:AI 辅助,摸清上下游。 让 agent 梳理目标模块的全部依赖——谁调用了它、它依赖谁、数据从哪来到哪去。这是人类 review 后续所有变更的前提。WELC 第 11-12 章讲的"影响示意图"和"拦截点",过去靠人肉 grep 和手画架构图,现在 agent 几分钟搞出一张完整的依赖地图。
第二步:补齐特征测试。 WELC 第 13 章的"特征测试"(Characterization Tests)是全书最实用的概念:你不需要知道代码应该干什么,你只需要记录它实际在干什么。 让 agent 对目标模块补充事无巨细的测试——每个逻辑分支走到、边界条件穷举、异常路径覆盖。测试就像橡胶模具,精确反映了原模块当前的行为特征。覆盖率不够就继续补,agent 时代成本极低。
第三步:重构,守住模具。 开始动代码。每改一步跑一遍特征测试,case 全绿 = 行为没变。有新特性就单独补新的测试 case,新旧测试共同构成防护网。
这就是 Feathers 第 2 章定义的标准算法:找修改点 → 找测试点 → 解依赖 → 写测试 → 修改并重构。 Agent 时代没有改变这个算法,只是把每一步的执行成本压到了极低。
3 小结
Feathers 二十年前的判断——没有测试的代码就是遗留代码——在 AI Coding 时代反而更精准了。Agent 急剧放大了代码的生产速度,但如果测试跟不上,你只是在更快地制造遗留代码。
好在造测试的成本同样被 agent 压到了极低。经典方法论 + agent 执行力,是当前阶段处理遗留代码的最优组合。
在新时代,经典的软件开发书籍往往给我们很多不变的准则,我们开发者也被迫要做顶层的 review 和审核。质量责任和工程 sense,可能成为人类开发者最后的护城河了。