#005-文档驱动项目-第五篇:从文档到重构——渐进式改造的实战路径
——文档不是终点,是改造的起点
系列导读:这是《老项目如何引入文档驱动》系列的第 5 篇。前四篇我们聊了为什么需要文档驱动、如何用 AI 理解代码、如何写出第一份 MVD、如何让文档持续维护。现在,更激动人心的事来了——如何用文档驱动老项目的重构?
小张的意外发现:文档成了"照妖镜"
小张是我们团队的高级工程师。3个月前,他按照前三篇的方法,给支付模块写了一份MVD。
写完后松了口气:"终于把文档补上了,新人应该能看懂了。"
但2周后,新人小王拿着文档来找他:"张哥,我按照文档理解的流程,和代码对不上啊。"
小张仔细一看:
文档说支付状态有5种,代码里有8种。
文档说回调逻辑在PaymentCallbackHandler,但代码里:
-
支付宝在PaymentCallbackHandler
-
微信在WeChatService
-
银行卡在BankCardController
他花了2天写的文档,现在看起来更像是"对现实的误解"。
但他很快意识到:不是文档写错了,而是代码本身就有问题。
写文档的过程,强迫他理清楚"应该是什么样",结果发现代码早就"走样"了。
这就是很多人写完文档后遇到的困境:文档像一面镜子,照出了代码的问题,但不知道怎么改。

小张的真实困境:重构之路并不顺利
你可能以为:小张从此开始了一帆风顺的重构之旅。
错了。
第 2 周:
小张开始细化问题清单时,发现问题远比想象的多。
不是 5 个问题,而是 12 个。
他开始怀疑:这些都要改吗?改得完吗?
团队 Leader 也来问:“你花了 2 周在文档上,什么时候开始做需求?”
第 4 周:
正当他准备重构状态管理时,客户催新需求:“这周五必须上线!”
重构计划被迫暂停。
他花了 3 天赶需求,又花了 2 天修 bug。
重构?只能先放一放。
第 5 周:
恢复重构后,他发现 AI 给的方案有漏洞。
AI 建议“将状态转换逻辑迁移到状态机”,但没考虑到数据库中已有的 8000 条历史订单。
迁移状态机?历史数据怎么办?
他花了 3 天重新设计兼容方案。
第 8 周:
状态管理终于重构完了,但回调逻辑呢?
他看了一眼代码,发现回调逻辑比想象的复杂 10 倍。
要不……先不改了?
小张的感悟:
“一开始以为‘发现问题 → 重构’很简单。”
“实际上,重构是一场持续的决策:改什么,不改什么,什么时候改。"
“不是所有问题都要立刻修,也不是所有重构都能完成。”
关键是:知道什么时候该停下来。

这篇文章就是要解决这个问题。
我们不追求“一次性大重构”,而是追求“渐进式改造”。
更重要的是:学会判断什么时候不该重构。
借助 AI 工具,基于文档驱动,让老项目一点点变好——但不强求完美。
核心洞察:文档不是终点,是改造的起点
很多人把文档当成“描述现状的工具”。
错了。
文档的真正价值,是暴露代码和理想状态的差距。
类比:
建筑师画施工图时,不是在“描述现场的钢筋混凝土”,而是在“设计理想的建筑”。
现场和图纸有差距?那就按图纸调整现场。
软件也一样。
写文档时,你描述的是“业务逻辑应该是什么样”,结果发现代码早就偏离了。
这个差距,就是重构的起点。
文档驱动重构的本质:
不是“用代码实现文档”,而是“用文档指引代码的演化”。
三个阶段:
-
用文档“照镜子”:发现代码的问题
-
用文档“画蓝图”:设计理想状态
-
用文档“做指南”:渐进式改造
接下来我们逐个拆解。
第一阶段:用文档“照镜子”——发现问题
写完文档后,不要急着重构。
第一步:让 AI 帮你找差异。
AI辅助对比:文档 vs 代码
小张让AI读一遍文档,再读一遍代码,然后问:"这两个说的一样吗?有什么不一致的地方?"
AI给出7个可能问题,小张花30分钟筛选,找到3个真问题:
1. 状态定义不一致
-
文档:5种状态
-
代码:8种状态(多了TIMEOUT、CANCELING、PARTIAL_REFUND)
-
影响:新增状态时容易出错
-
建议:确认这3种状态是否必要
2. 回调处理逻辑分散
-
文档:描述统一的回调处理流程
-
代码:3种支付方式的回调分散在不同类中
-
问题:违反单一职责原则,不易维护
-
建议:考虑重构为统一的回调处理器
3. 异常处理不统一
-
文档:描述了超时重试机制
-
代码:只有支付宝有重试,微信和银行卡没有
-
问题:行为不一致,可能导致用户体验差异
-
建议:统一异常处理策略
**AI的其他4个"问题"经验证是误报:**订单号生成(AI没看懂分布式ID)、数据库事务(实际是合理设计)、日志记录(优先级低)、缓存失效(是实现细节)。
AI不是100%准确,但它帮你快速定位可能的问题。你的任务是花30分钟筛选,找出真正需要处理的。
**独立开发者的快捷方式:**如果时间紧,跳过AI对比,直接问自己:"写文档时,哪里最难描述?哪里说不清楚?"难描述的地方,往往就是代码有问题的地方。

识别“坏味道”:不只是差异,更是设计问题
除了文档-代码不一致,还要识别更深层的“坏味道”。
常见的坏味道:
| 坏味道 | 表现 | 文档能暴露吗? |
|---|---|---|
| 状态混乱 | 状态转换没有明确规则 | ✅ 写文档时发现“状态图画不出来” |
| 逻辑分散 | 同一个业务流程散落在多个类中 | ✅ 写文档时发现“要引用 5 个类” |
| 命名不一致 | 同样的概念用了不同的词 | ✅ 写文档时发现“用词混乱” |
| 隐式依赖 | 代码之间有隐藏的依赖关系 | ✅ 写文档时发现“顺序很重要但没说明” |
小张的发现:
他写文档时,发现支付状态的转换规则“说不清楚”。
为什么?
因为代码里的状态转换是隐式的,散落在 8 个方法里,没有统一的状态机。
这就是坏味道。
建立问题清单:不要立刻修
发现问题后,不要立刻动手改。
先建一个“问题清单”。
小张的问题清单:
# 支付模块问题清单
## 高优先级(影响业务逻辑)
1. 状态转换规则不明确
- 问题:状态机隐式,散落在多个方法
- 影响:新增状态时容易出错
- 建议:重构为显式状态机
2. 回调逻辑分散
- 问题:3 种支付方式的回调分散在不同类
- 影响:维护成本高,行为不一致
- 建议:统一为 CallbackHandler
## 中优先级(影响可维护性)
3. 异常处理不统一
- 问题:只有支付宝有重试逻辑
- 影响:用户体验不一致
- 建议:提取通用异常处理
4. 命名不一致
- 问题:"订单"有时叫 Order,有时叫 Payment
- 影响:理解成本高
- 建议:统一术语
## 低优先级(技术债务)
5. 测试覆盖不足
- 问题:核心流程测试覆盖率 < 40%
- 影响:重构风险高
- 建议:先补测试再重构
不是所有问题都要立刻修,而是先分优先级。
**高优先级:**影响业务逻辑,必须修
**中优先级:**影响可维护性,可以逐步修
**低优先级:**技术债务,长期规划
第二阶段:用文档“画蓝图”——设计理想状态
有了问题清单,接下来不是“改代码”,而是“画蓝图”。
在文档中先设计“理想的架构”。
在文档中设计理想状态
小张的做法:
他在文档中新增了一个章节:“理想的架构设计”。
理想的状态管理:
## 理想的状态管理
支付状态采用显式状态机:
状态定义:
- CREATED:订单创建
- PAYING:支付中
- PAID:支付成功
- FAILED:支付失败
- REFUNDED:已退款
状态转换规则:
- CREATED → PAYING:用户发起支付
- PAYING → PAID:收到支付成功回调
- PAYING → FAILED:支付超时或失败
- PAID → REFUNDED:用户发起退款
禁止的转换:
- PAID 不能回到 PAYING
- FAILED 不能直接到 PAID
理想的回调处理:
## 理想的回调处理
统一的回调处理器 PaymentCallbackHandler:
职责:
- 接收所有支付方式的回调
- 验证回调签名
- 更新支付状态
- 触发后续业务流程(如发货)
不同支付方式的差异通过策略模式处理:
- AlipayCallbackStrategy
- WeChatCallbackStrategy
- BankCardCallbackStrategy
不是直接写代码,而是先在文档中"设计"理想状态。
**这样做的好处:**成本低(改文档比改代码快)、易讨论(团队可以基于文档讨论方案)、可回滚(设计不合理,直接删掉重来)。
**独立开发者的快捷方式:**如果时间紧,跳过"理想架构"的详细设计,只写一句话描述:"理想状态是XXX,当前差距是YYY,改的话要做ZZZ"。够判断要不要改就行了。

用 AI 模拟重构方案
设计完理想状态,让 AI 帮你模拟重构方案。
小张的做法:
他把“当前代码”和“理想设计”喂给 AI,问:
“如何从当前状态重构到理想状态?给出分步方案。”
AI 的输出:
重构方案(3 个阶段):
阶段 1:建立状态机(2 周)
1. 创建 PaymentStateMachine 类
2. 定义状态枚举和转换规则
3. 将现有的状态转换逻辑迁移到状态机
4. 保留旧代码作为兼容层
风险:中等
影响范围:支付创建、状态更新
阶段 2:统一回调处理(3 周)
1. 创建 PaymentCallbackHandler
2. 提取各支付方式的共同逻辑
3. 用策略模式处理差异
4. 逐个迁移支付方式(支付宝 → 微信 → 银行卡)
风险:高
影响范围:所有支付回调
阶段 3:清理旧代码(1 周)
1. 删除兼容层
2. 统一命名
3. 补充测试
风险:低
影响范围:代码清理
总耗时:6 周
建议:先做阶段 1,验证效果后再做阶段 2
AI给的方案是"起点",而不是"终点"。
你需要基于AI的方案,再做一遍风险评估和调整。
AI帮你节省了50%的时间,但剩下的50%还是要靠你的经验和判断。
评估风险:哪些能改,哪些不能碰
不是所有代码都值得重构。
评估标准:
| 代码特征 | 是否重构 | 理由 |
|---|---|---|
| 核心业务逻辑 | ✅ 重构 | 影响大,必须清晰 |
| 临时解决方案(workaround) | ✅ 重构 | 长期运行会变成技术债务 |
| 边缘功能(使用率 < 5%) | ❌ 不碰 | 投入产出比低 |
| 稳定运行多年的代码 | ❌ 不碰 | "能跑就别动" |
小张的评估:状态机和回调处理是核心业务,必须重构;对账功能是边缘功能,暂不重构。
第三阶段:用文档“做指南”——渐进式重构
有了蓝图和方案,开始真正的重构。
但不是“大刀阔斧”,而是“小步快跑”。
小步快跑:每次只改一小块
小张的第一步:
他没有一次性重构整个状态管理,而是:
第 1 周:只重构状态定义
-
创建 PaymentState 枚举
-
明确 5 种状态
-
其他代码暂不动
第 2 周:引入状态机基础框架
-
创建 PaymentStateMachine 类
-
定义状态转换规则
-
但暂时不迁移业务逻辑
第 3 周:迁移创建支付的状态转换
-
只迁移 CREATED → PAYING 这一个转换
-
其他转换还用旧代码
第 4 周:逐步迁移其他状态转换
-
每次迁移 1-2 个转换
-
每次都测试验证
每次只改一小块,随时可以停下来或回滚。不要追求"一次改完"。

文档先行:先更新文档,再改代码
每次重构前,先在文档中更新“当前状态”。
小张的做法:
他的文档中有两个版本:
-
当前实现(Current):描述代码现状
-
理想设计(Target):描述目标架构
每次重构后,更新“当前实现”,缩小和“理想设计”的差距。
示例:
## 状态管理
### 当前实现(v0.3,更新于 2024-12-01)
- ✅ 已引入 PaymentState 枚举
- ✅ 已引入 PaymentStateMachine
- ✅ CREATED → PAYING 已迁移到状态机
- 🔄 其他状态转换还在旧代码中
### 理想设计(Target)
- 所有状态转换由 PaymentStateMachine 统一管理
- 旧代码完全清理
团队随时能看到"进度"和"差距"。
AI 辅助:生成重构代码建议
每次重构时,让 AI 生成代码建议。
小张的做法:
他把“当前代码”和“文档中的理想设计”喂给 AI,问:
“如何将当前代码重构为理想设计?只重构状态转换部分。”
AI 的输出:
建议的重构步骤:
1. 创建状态机类
- 类名:PaymentStateMachine
- 方法:transition(from, to, event)
- 返回:转换是否成功
2. 迁移 createPayment 方法
旧代码:
payment.setStatus(PaymentStatus.PAYING);
新代码:
stateMachine.transition(payment, CREATED, PAYING, "USER_PAY");
3. 测试验证
- 单元测试:验证状态机规则
- 集成测试:验证创建支付流程
AI生成的代码不一定能直接用,但它给了你一个起点。你可以在此基础上调整,而不是从零开始。
独立开发者的轻量重构路径
看到这里,独立开发者可能会想:
“我哪有 3 个月时间重构?客户的需求还等着呢!”
别急,有更轻量的做法。
更重要的是:先判断要不要重构。
第零步:判断要不要重构(5 分钟决策)

不是所有问题都值得重构。
用这个决策表,5 分钟判断:
| 判断维度 | 要重构 | 不重构 |
|---|---|---|
| 问题影响范围 | 客户会遇到 bug | 只影响自己理解代码 |
| 改动风险 | 相对安全,有测试覆盖 | 改了可能崩,测试不足 |
| 时间成本 | < 1 天 | > 3 天 |
| 项目生命周期 | 还要运行 1 年+ | 临时项目,3 个月后下线 |
| 你的状态 | 有空闲时间 | 客户催得紧 |
示例判断:
场景 1:支付状态管理混乱
-
影响范围:✅ 客户会遇到 bug(状态错了,钱会出问题)
-
改动风险:⚠️ 有风险,但有测试
-
时间成本:⚠️ 需要 2-3 天
-
项目生命周期:✅ 还要运行 2 年
-
你的状态:⚠️ 客户有新需求,但不算太急
结论:重构,但分步做,不一次性完成。
场景 2:对账功能代码很乱
-
影响范围:❌ 只影响自己(对账是后台任务,很少改)
-
改动风险:❌ 没测试,改了可能崩
-
时间成本:❌ 需要 5 天
-
项目生命周期:⚠️ 还要运行 1 年
-
你的状态:❌ 客户催得很紧
结论:不重构,只在文档中标记“危险区域”。
不是"发现问题就要改",而是"评估值不值得改"。独立开发者的时间有限,要把精力用在刀刃上。
极简重构方案:3 个档位

根据时间和紧急程度,选择不同的重构档位。
档位 1:5 分钟——只标记,不改代码
适用场景:
-
发现了问题,但现在没时间改
-
客户催得紧,不能停下来重构
具体做法:
在文档中标记问题,但不动代码。
## 状态管理
### ⚠️ 已知问题(未修复)
1. 状态转换逻辑分散在 8 个方法中
- 风险:新增状态时容易出错
- 建议:重构为统一状态机
- **决策:暂不修复**(时间成本 3 天,收益中等)
- 触发时机:下次大改状态逻辑时再重构
### ⚠️ 危险区域(不要动)
- `PaymentService.updateStatus()` 方法
- 问题:逻辑混乱,但很稳定
- 建议:**不要改**,除非出 bug
- 如果必须改:先补测试,再小心修改
效果:
-
5 分钟标记完成
-
未来的自己(或新人)看到标记,知道这里有坑
-
避免重复踩坑,或者无意中改出问题
档位 2:半天——只重构当前要改的部分
适用场景:
-
有新需求,需要改这块代码
-
不改根本动不了,改了才能继续
具体做法:
不追求“整体重构”,只重构当前要改的那块代码。
示例:
客户要求新增“部分退款”功能。
**传统做法:**直接在旧代码上加 if-else,让代码更乱。
档位 2 做法:
-
只重构状态转换部分(和新需求相关)
-
提取
handleRefund()方法 -
明确状态转换规则
-
不动其他代码
-
-
更新文档
-
标记:已重构状态转换部分
-
标记:其他部分还是乱的
-
时间成本:
-
重构:4 小时
-
新需求:2 小时
-
总共:半天
效果:
-
新需求完成了
-
代码略微改善了(不是全部,但也够用)
-
下次改这块代码时,会更容易
档位 3:3 天内——借新需求,顺手重构相关模块
适用场景:
-
这块代码很乱,一直想重构
-
刚好有个新需求涉及这块
-
时间相对宽裕(客户不是特别急)
具体做法:
趁新需求,顺手重构整个相关模块。
示例:
客户要求支持“银联支付”。
传统做法:
复制粘贴支付宝的代码,改改参数,勉强能用。
档位 3 做法:
-
趁这次需求,重构整个回调处理
-
提取共同逻辑到
PaymentCallbackHandler -
用策略模式处理支付宝、微信、银联的差异
-
统一异常处理和日志记录
-
-
更新文档
-
描述新的回调处理架构
-
标记:已重构完成
-
时间成本:
-
重构:2 天
-
新需求:1 天
-
总共:3 天
效果:
-
新需求完成了
-
代码质量大幅提升
-
下次接入新支付方式,只需要半天
不是"为了重构而重构",而是"借需求之力,顺手重构"。3个档位,根据实际情况选择。不强求档位3,档位1和2也是进步。
真实案例:独立开发者的“被迫重构”
背景:
张三是一名独立开发者,同时维护 3 个客户的项目。
其中一个项目是电商平台,支付模块代码很乱(历史遗留,不是他写的)。
困境:
客户突然要求:“支持微信支付,这周五上线。”
张三看了一眼代码,崩溃了:
-
支付宝的回调逻辑散落在 4 个文件里
-
状态管理没有统一规则
-
测试覆盖几乎为零
他试图直接加微信支付,发现根本改不动——代码太乱了。
决策:被迫重构(档位 2)
张三意识到:不重构,新需求根本做不了。
但他没有时间整体重构,只能“局部重构”:
第 1 步:只重构回调处理逻辑(4 小时)
-
提取支付宝回调的共同逻辑
-
创建
CallbackHandler接口 -
不动其他代码
第 2 步:接入微信支付(2 小时)
-
实现
WeChatCallbackHandler -
复用共同逻辑
第 3 步:更新文档(30 分钟)
-
标记:已重构回调处理
-
标记:状态管理还是乱的(下次再改)
结果:
-
周五按时上线
-
代码质量略微改善(不是全部,但也够用)
-
下次接入新支付方式,会更容易
张三的感悟:
“独立开发者没有理想的重构时间,只有‘被迫重构’的机会。”
“关键是:抓住机会,顺手改一点,而不是追求完美。”
当重构变成“坑”时怎么办

重构不是总能成功,有时会变成“坑”。
3 个真实的“坑”,和应对策略:
坑 1:重构到一半,发现改不动
场景:
你开始重构状态管理,改到一半发现:历史数据格式和新设计不兼容。
要么大改数据库(风险高),要么放弃重构。
错误做法:
硬着头皮继续,结果改了 2 周,代码更乱了。
正确做法:
果断回滚,标记为“危险区域”。
## 状态管理
### ⚠️ 重构失败记录(2024-12-01)
- 尝试:引入统一状态机
- 失败原因:历史数据格式不兼容,迁移成本太高
- 决策:放弃重构,保持现状
- **标记:危险区域,不要动**
- 如果未来必须改:先设计数据迁移方案
效果:
-
及时止损,没有让代码更乱
-
记录失败原因,避免下次重复尝试
-
明确告诉未来的自己:“这里不能动”
坑 2:重构后性能变差
场景:
你重构了回调处理,代码结构清晰了,但性能下降了 20%。
客户投诉:“支付变慢了。”
错误做法:
继续优化性能,结果又花了 1 周,代码又变复杂了。
正确做法:
记录问题,先回滚到旧版本。
## 回调处理
### ⚠️ 重构后性能问题(2024-12-01)
- 问题:新架构性能下降 20%
- 原因:每次回调都会查询数据库,旧代码用了缓存
- 决策:暂时回滚,标记为"待优化"
- 下次有时间再优化:加缓存层
效果:
-
客户体验不受影响(性能恢复)
-
记录问题,下次有时间再优化
-
不强求“一次性完美”
坑 3:客户催得紧,重构被迫停止
场景:
你正在重构状态管理,改到一半,客户突然催新需求:“必须今天上线!”
错误做法:
一边重构一边赶需求,结果代码半新半旧,bug 一堆。
正确做法:
立刻停止重构,先交付需求。
## 状态管理
### 🔄 重构暂停(2024-12-01)
- 进度:已完成 40%
- 原因:客户催需求,优先交付
- 决策:暂停重构,保持当前状态
- 恢复时间:待定(需求交付后再评估)
- **标记:代码半新半旧,谨慎修改**
效果:
-
客户需求按时交付
-
代码虽然半新半旧,但至少能跑
-
明确告诉未来的自己:“这里在重构中,小心”
重构不是"一定要完成",而是"随时可以停"。客户需求 > 代码重构。先保证业务,再考虑代码质量。
不重构也能改善:文档就够了

有些情况,文档就够了,不需要重构代码。
这不是“偷懒”,而是“务实”。
场景 1:代码很乱,但很稳定
典型情况:
对账功能的代码,逻辑混乱,变量命名糟糕,但已经稳定运行 2 年,零 bug。
传统想法:
“这代码太乱了,必须重构!”
务实做法:
只写文档,不动代码。
## 对账功能
### ⚠️ 代码质量警告
- 问题:逻辑混乱,变量命名糟糕
- 但是:**非常稳定**,2 年零 bug
- **决策:不要动这块代码**
- 原因:"能跑就别动",重构风险 > 收益
### 如果必须修改
1. 先补测试(测试覆盖率至少 80%)
2. 小范围试点(先改一小块)
3. 灰度发布(观察 1 周再全量)
### 核心逻辑说明
- 第 1 步:查询订单...
- 第 2 步:对比金额...
- [用文档解释代码逻辑,而不是重构代码]
效果:
-
零成本(只写文档,不改代码)
-
新人看文档能理解逻辑
-
避免“改出新 bug”的风险
场景 2:临时项目,不值得投入
典型情况:
一个客户的临时项目,预计运行 3 个月就下线。
代码写得很赶,问题一堆。
传统想法:
“虽然是临时项目,但代码质量也要保证啊!”
务实做法:
写个“避坑指南”,而不是重构。
## 临时项目:XX 活动页
### ⚠️ 项目特征
- 生命周期:3 个月(2024-12 ~ 2025-02)
- 代码质量:较差(赶工完成)
- **决策:不投入重构**(项目会下线)
### 避坑指南
1. **定时任务的坑**
- 问题:定时任务没加锁,可能重复执行
- 影响:数据可能重复
- **绕过方法**:手动检查数据,别依赖自动化
2. **缓存失效的坑**
- 问题:缓存 key 设计不合理,可能不失效
- 影响:数据更新后,用户看到的还是旧数据
- **绕过方法**:每次改数据后,手动清缓存
3. **数据库字段的坑**
- 问题:`status` 字段类型是字符串,应该是枚举
- 影响:查询慢,容易写错
- **绕过方法**:用常量定义状态值,别直接写字符串
效果:
-
极低成本(30 分钟写完)
-
避免踩坑,节省时间
-
项目下线后,文档也没用了,无需维护
场景 3:自己也看不懂的历史代码
典型情况:
接手一个老项目,核心逻辑的代码,自己也看不懂。
原开发者已经离职,没人能解释。
传统想法:
“看不懂就重构呗,重新写一遍。”
务实做法:
用 AI 生成“考古报告”,理解意图即可,不求重构。
## 核心算法:价格计算逻辑
### ⚠️ 代码现状
- 问题:看不懂,原开发者离职
- 风险:重构可能改出 bug
- **决策:不重构,只理解意图**
### AI 生成的逻辑分析
(让 AI 读代码,生成逻辑说明)
这段代码的核心逻辑:
1. 计算基础价格
2. 应用会员折扣(有 3 层折扣)
3. 应用优惠券
4. 四舍五入到分
关键决策:
- 为什么折扣有 3 层?可能是历史原因
- 为什么四舍五入?财务要求
### 已知边界情况
- 价格 = 0 时,直接返回(不计算折扣)
- 会员等级 > 3 时,按等级 3 处理
- [从测试用例中推断出的边界]
### ⚠️ 不要动这块代码
- 原因:看不懂,风险太高
- 如果必须改:先写全面的测试,再小心修改
效果:
-
理解了意图(虽然看不懂代码,但知道它在干嘛)
-
避免了风险(没有盲目重构)
-
给未来留下线索(下次看代码时,有个参考)
不是所有问题都要通过重构解决,有时候文档就够了。"够用"比"完美"更重要,尤其是独立开发者。
真实案例:支付模块的渐进式改造(修订版)

回到小张的故事。
他用 6 个月,渐进式改造了支付模块——但不是全部完成,而是“有选择地完成”。
第 1 个月:文档揭示了 5 个问题
-
用 AI 对比文档和代码,发现 5 个主要问题
-
建立问题清单,排优先级
-
在文档中设计“理想架构”
**投入:**每周 8 小时
**产出:**问题清单 + 理想架构文档
第 2 个月:开始重构,但被迫暂停
-
开始重构状态管理,写了一半
-
客户突然催新需求:"必须这周五上线!"
-
团队leader质疑:"你这是在重构还是在拖延需求?"
-
小张妥协了:决策:暂停重构,先交付需求
**投入:**累计2周(每周10小时),但只完成40%
**产出:**半成品状态机(暂时不能用)
小张的感悟:"计划赶不上变化,重构不能影响业务。被leader质疑的那一刻,我意识到:业务永远比代码重要。"
第 3 个月:恢复重构,但发现 AI 的方案有漏洞
-
恢复重构,发现 AI 没考虑历史数据兼容
-
花了 3 天重新设计兼容方案
-
最终完成状态管理重构
**投入:**累计 3 周(每周 12 小时)
**产出:**状态管理模块重构完成,测试覆盖率 80%
效果:
-
新增状态的时间从 2 天缩短到 4 小时
-
状态相关的 bug 减少 60%
第 4 个月:评估回调逻辑,决定不重构
-
开始评估回调逻辑重构
-
发现比想象的复杂10倍:涉及3种支付方式、历史订单、第三方依赖
-
看着10页的重构方案,小张突然意识到:不是所有债务都要还。
-
决策:暂不重构,只在文档中标记为"技术债务"
**投入:**1周(评估方案)
**产出:**回调逻辑重构方案(但决定不执行)
小张的感悟:
"不是所有问题都要立刻修,有些债务可以慢慢还。这个决策让我解脱了——我不再追求'完美重构'。"
第 6 个月:总结和文档更新
-
完成状态管理重构(✅ 已完成)
-
回调逻辑标记为技术债务(❌ 未完成)
-
更新文档,标记哪些已改,哪些未改
最终成果:
-
代码质量有改善(不是全部,但够用)
-
新人 onboarding 时间从 1 周缩短到 3 天
-
团队建立了“渐进式改造”的习惯
小张的最终感悟:
"一开始以为'发现问题 → 全部重构'。"
"实际上,重构是'选择性完成':改最重要的,其他的标记为债务,慢慢还。"
"6个月后,我没有完成所有重构,但代码确实变好了。更重要的是,我学会了判断:什么时候该停下来。"
不是"完美重构",而是"够用就好"。
到目前为止,我们的系列已经完成:
-
第1篇:为什么老项目需要文档驱动?
-
第2篇:让AI帮你理解遗留代码
-
第3篇:写出第一份最小可行文档
-
第4篇:让文档"活"起来——建立可持续的维护机制
-
第5篇:从文档到重构——渐进式改造的实战路径
下一篇:
第6篇:规模化实践——从个人项目到团队协作
我们将讨论:
-
如何在团队中推广文档驱动?
-
如何处理团队的阻力?
-
如何建立团队的文档文化?
敬请期待!