Skip to main content
← All posts
作者:Sagasu

#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 工具,基于文档驱动,让老项目一点点变好——但不强求完美。


核心洞察:文档不是终点,是改造的起点

很多人把文档当成“描述现状的工具”。

错了。

文档的真正价值,是暴露代码和理想状态的差距。

类比:

建筑师画施工图时,不是在“描述现场的钢筋混凝土”,而是在“设计理想的建筑”。

现场和图纸有差距?那就按图纸调整现场。

软件也一样。

写文档时,你描述的是“业务逻辑应该是什么样”,结果发现代码早就偏离了。

这个差距,就是重构的起点。


文档驱动重构的本质:

不是“用代码实现文档”,而是“用文档指引代码的演化”。


三个阶段:

  1. 用文档“照镜子”:发现代码的问题

  2. 用文档“画蓝图”:设计理想状态

  3. 用文档“做指南”:渐进式改造

接下来我们逐个拆解。


第一阶段:用文档“照镜子”——发现问题

写完文档后,不要急着重构。

第一步:让 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 做法:

  1. 只重构状态转换部分(和新需求相关)

    • 提取 handleRefund() 方法

    • 明确状态转换规则

    • 不动其他代码

  2. 更新文档

    • 标记:已重构状态转换部分

    • 标记:其他部分还是乱的

时间成本:

  • 重构:4 小时

  • 新需求:2 小时

  • 总共:半天

效果:

  • 新需求完成了

  • 代码略微改善了(不是全部,但也够用)

  • 下次改这块代码时,会更容易


档位 3:3 天内——借新需求,顺手重构相关模块

适用场景:

  • 这块代码很乱,一直想重构

  • 刚好有个新需求涉及这块

  • 时间相对宽裕(客户不是特别急)

具体做法:

趁新需求,顺手重构整个相关模块。

示例:

客户要求支持“银联支付”。

传统做法:
复制粘贴支付宝的代码,改改参数,勉强能用。

档位 3 做法:

  1. 趁这次需求,重构整个回调处理

    • 提取共同逻辑到 PaymentCallbackHandler

    • 用策略模式处理支付宝、微信、银联的差异

    • 统一异常处理和日志记录

  2. 更新文档

    • 描述新的回调处理架构

    • 标记:已重构完成

时间成本:

  • 重构: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篇:规模化实践——从个人项目到团队协作

我们将讨论:

  • 如何在团队中推广文档驱动?

  • 如何处理团队的阻力?

  • 如何建立团队的文档文化?

敬请期待!