记录一次用 claude code 重构遗留代码的真实体验
我清晰地记得那个周二下午,产品经理第三次问我:“这个功能真的不能加吗?竞品已经上线两个月了。”
不是我不想加。而是我手里那个 2018 年上线的订单管理模块,代码行数超过 4.2 万行,核心业务逻辑塞在一个叫做 OrderService.java 的文件里,单文件 3700 行,最长的 processRefund() 方法有 840 行。注释比例不到 3%,最早的一行注释写着“// 临时方案,后面优化”,提交时间是 2019 年 3 月。
我在这个项目上已经花了 11 个月。前 3 个月在理解逻辑,中间 4 个月在修 bug,最近 4 个月试图重构,失败了两次。第一次因为改动太大导致回归测试全红,第二次因为业务方等不及,我被迫回退代码。
这次,我决定让 Claude Code 当我的重构搭档。
核心结论先放在这里:它不是什么魔法棒,而是一个能听懂你说话、能理解项目上下文、但绝对需要你持续质疑和验证的编程伙伴。 整个重构过程一共 7 个工作日,涉及 12 个核心文件,最终代码行数从 4.2 万降到 2.8 万(减少 33%),单元测试覆盖率从 8% 提升到 71%。但中间翻车 4 次,有一次差点把生产环境的退款逻辑改出 bug。
这篇文章,我要记录的是真实的协作过程,不是“我一说需求 AI 就搞定了”的爽文,而是那种你需要引导它、纠正它、甚至和它“谈判”的团队协作体验。
一、这个“屎山”项目到底烂到什么程度
1.1 接手时的真实状况
先交代技术栈:Java 8 + Spring Boot 2.0 + MyBatis,部署在内部私有云上。订单模块是电商系统的核心,负责下单、支付回调、退款、订单状态流转。2019 年之后基本没人敢大改过。
我做了个简单统计:
| 指标 | 数据 | 我的评价 |
|---|---|---|
| 总代码行数 | 42,380 行 | 一个模块顶别人三个微服务 |
| 最大单文件行数 | 3,742 行 | IDE 打开要卡 3 秒 |
| 注释覆盖率 | 2.7% | 几乎为零 |
| 单元测试覆盖率 | 8% | 四舍五入等于没有 |
| 循环依赖数 | 7 处 | 启动日志里一堆警告 |
| 硬编码配置项 | 超过 60 个 | 数据库地址写在代码里 |
这不是“代码有点烂”,这是你接手之后每天想离职的程度。
1.2 为什么不早重构
不是没试过。我们团队前后尝试过两次手动重构:
- 第一次(2023 年 6 月):计划用 3 周拆分 OrderService,第二周就放弃了。因为方法之间的调用关系盘根错节,改一个 private 方法会影响到 30 多个调用点。
- 第二次(2023 年 11 月):尝试先补充单元测试再重构。但写测试本身就极其困难,一个方法要 mock 十几个依赖,sql 语句嵌在业务逻辑里,根本测不了。
通俗地说:代码耦合度太高,动一个小地方就像碰了一根线,整个蜘蛛网都在抖。
1.3 重构前的风险判断
在引入 Claude Code 之前,我做了三个判断:
- 不能全量重写:业务方不会接受“停下手头需求,让我们重构三个月”。必须在保持功能正常的前提下逐步替换。
- 必须建立安全网:没有测试的重构就是裸奔。无论如何,先要有基本的回归测试。
- 理解业务逻辑是最大成本:AI 能帮我写代码,但它需要我来告诉它“这段代码要干什么”,而我自己也得搞清楚。
我当时记了一笔账:
如果人工重构,预计需要 2 个后端 + 1 个测试,投入 6-8 周,总成本约 30-40 人天。
如果让 AI 辅助,我作为主力 + 另一个同事 Review,预计 2-3 周,总成本约 12-15 人天。
但前提是:AI 真的能理解这套烂代码。

二、为什么选 Claude Code,而不是 Cursor 或 Copilot
2.1 三大 AI 编程工具的对比经验
我用过 GitHub Copilot 一年半,用过 Cursor 三个月,用过 ChatGPT 的代码解释。选择 Claude Code 不是因为它“最强”,而是因为在这个场景下它最合适。
Claude Code 最大的差异化优势:理解长上下文和项目结构。
让我用一个真实的对比来说明。
2024 年 1 月,我曾经尝试用 Cursor 分析这套订单系统。我把 OrderService.java 拖进去,让它帮我梳理退款流程。它给出的回答是:
“这个文件似乎处理多种订单状态,包括支付、发货、退款等。具体的退款逻辑可能在 processRefund 方法中……”
,这相当于告诉我“饭可能在厨房里”。但厨房结构如何、第一步该干什么、有哪些边界条件,它没说。
同样的文件给到 Claude Code(通过 CLI 模式嵌入项目目录),它给出了:
“我分析了 OrderService.java 及相关 12 个引用文件。退款流程涉及以下路径:
- OrderController.refund() 接收请求,调用 OrderFacade.refundApply()
- OrderFacade 做了状态校验(但缺少并发锁控制)
- 实际的退款计算在 OrderServiceImpl.processRefund() 第 847-1120 行
- 这个方法有 3 个嵌套的 if-else 分支,分别处理‘全部退款’‘部分退款’‘运费补贴’
- 我发现第 1023 行有一个潜在的空指针风险:代码先调用了 order.getPayChannel().getRefundRate(),但没有判断 payChannel 是否为空。”
这个对比说明了核心差异:
- Copilot / Cursor 擅长行级补全和当前文件理解
- Claude Code 能跨文件追踪调用链、识别隐藏的依赖关系、发现潜在的 bug

2.2 第一个测试:让 Claude Code 给我讲一遍业务
正式开始重构前,我做了个试验。我在项目根目录下启动 Claude Code,给了它这样一段 prompt:
“这是我们的订单系统,核心目录在 order-module 下。请你在不修改任何代码的前提下,帮我梳理以下几个问题:
- 退款流程的完整调用链路是怎样的?
- 有哪些地方可能出现并发问题?
- 哪些方法缺少必要的事务注解?”
Claude Code 花了大约 4 分钟扫描代码(项目约 400 个 Java 文件),然后给出了回答。我把它梳理的结果和我知道的情况做了对比:
| 检查项 | Claude Code 发现 | 我的验证结果 |
|---|---|---|
| 退款调用链 | 准确,8 个关键节点 | 正确 |
| 并发风险点 | 指出 4 处 | 其中 3 处确实存在,1 处因为上游做了分布式锁,误报 |
| 缺少事务注解 | 指出 11 处方法 | 我确认其中 8 处确实需要加 @Transactional |
| 死代码 | 指出 3 段无法到达的代码 | 全部正确,其中一段是 2019 年的灰度逻辑 |
这个试验让我建立了基本信任:它能读懂项目,但不是 100% 准确。我需要验证它的每一个判断。
2.3 关键决策:不让 AI 直接写代码,先让它写分析文档
基于上面的试验,我做了一个后来证明非常正确的决定:第一轮对话不让 AI 改任何代码,只让它生成重构分析和测试用例。
这样做有两个好处:
- 我和 AI 先对齐“对业务的理解”,避免它在错误的理解上写代码
- 生成的测试用例可以作为安全网,后续改代码时有保障
我让 Claude Code 生成了三份文档:
- 《订单模块业务逻辑梳理》(14 页,包含 7 个核心流程的状态图描述)
- 《重构风险点清单》(31 条具体风险,按严重程度分级)
- 《单元测试计划》(目标覆盖率 70%,预计 200+ 个测试用例)
这三个文档花了大约一天时间(包括我审查和修改的时间)。如果没有 AI,光梳理业务逻辑可能就要花我一周。
三、第一次“重构实战”:AI 给我的惊喜和惊吓
3.1 【高光时刻】拆分 OrderService:它用了 4 轮对话
第一个重构任务是最难的:把 3700 行的 OrderService 拆成 3 个职责清晰的服务类。
按照我的计划,应该拆成:
OrderQueryService:负责读操作OrderCommandService:负责写操作RefundService:专门处理退款逻辑
我把需求告诉了 Claude Code。第一轮生成的结果让我眼前一亮,它不光是拆分文件,还自动做到了:
- 识别出 23 个只在读操作中使用的 private 方法,归入 QueryService
- 发现 7 个被多处调用的工具方法,单独提取到 OrderUtils
- 修正了方法间的循环引用(这被它当初识别为风险点)
但问题也来了。它改了 3 个 public 方法的签名,理由是“这样更符合单一职责原则”。
我立刻叫停:
“你不能改 public 方法的签名,哪怕你的想法更好。这些方法是给前端和第三方调用方用的,改了之后所有调用方都得改,这在本次重构中不接受。”
Claude Code 当时的回应让我印象深刻:
“明白了,我基于‘最小化对外部接口的影响’重新调整拆分策略。我将保持所有 public 方法签名不变,仅从内部实现层面做拆分。”
这是我和它之间的一次关键“对齐”:重构的边界不是“怎么合理怎么来”,而是“在保持外部契约不变的前提下,让内部更合理”。
第二轮它重新生成,这次保留了所有 public API。但我又发现一个新问题:它把一个叫 calculateDiscount() 的方法完整地复制到了两个新的 Service 里,产生了代码重复。
我用很直接的方式纠正它:
“
calculateDiscount()现在出现在 QueryService 和 CommandService 两个文件里,代码一模一样。请把它提取到一个公共位置,两边引用而不是复制。”
第三轮,它修正了这个问题。但在单元测试里犯了个新错,mock 了一个已经被删除的内部方法。我指出之后,第四轮全部修正完毕。
整个过程花了大约 2.5 小时。如果我自己手动拆分,以前的经验告诉我至少需要两天。
不是因为 AI 比自己写更快,而是因为它承担了“找出所有依赖关系、把代码归位、生成对应的单元测试”这些高强度低创造性的工作。 我做的更多是“审查和决策”。

3.2 【翻车现场】它“发明”了一个不存在的 API
第二次翻车比第一次严重得多。
在重构支付回调处理逻辑时,我需要 Claude Code 把硬编码的支付渠道判断改成策略模式。原先的代码用了一大堆 if-else:
if ("alipay".equals(channel)) {
// 支付宝逻辑
} else if ("wechat".equals(channel)) {
// 微信逻辑
} else if ("unionpay".equals(channel)) {
// 银联逻辑
}
这个重构本身不难,Claude Code 很快生成了策略模式的代码。但在微信支付的回调处理中,它写了一行:
String decryptData = WechatPayUtils.decryptNotify(cipherText, apiV3Key);
我在审查时觉得这个方法名看起来合理,但总觉得哪里不对。查了我们项目里 WechatPayUtils 的源码,并没有这个静态方法。再查微信官方 SDK,微信支付 v3 的解密 API 是 AesUtil.decryptToString(),根本不是一个工具类里的方法。
Claude Code 凭空“创造”了一个看起来合理、但实际不存在的 API。
如果我当时没有逐行审查,而只是跑了一下单元测试,可能也不会发现,因为它在单元测试里 mock 了这个方法。只有集成测试才能暴露这个问题。
这个发现让我出了一身冷汗。我开始意识到:AI 在生成代码时,有时会基于“知识图谱里的相似模式”拼出一个不存在的东西。它不知道这个方法在这个项目里、在这个版本的 SDK 里不存在。
我截了一张当时的对话记录给团队看:
我:
WechatPayUtils.decryptNotify这个方法不存在,你看下我们的项目里实际怎么做的解密。Claude Code:抱歉,我确实没有在项目中发现这个方法。请允许我重新搜索项目中的微信解密实现。
(搜索后)找到了,项目中实际使用的是
WxPayCipher.decrypt(),我将用这个替换。
这个翻车经历让我定下一条铁律:所有 AI 引入的新方法调用,必须确认它真实存在于项目的依赖中。 后来的重构中,我要求 Claude Code 在引入外部 API 时,先标注出来让我确认。
3.3 【另一个高光时刻】写单元测试:超越我的预期
如果说代码重构是“惊喜和惊吓参半”,那写单元测试就是 Claude Code 最稳定的强项。
在我重构退款逻辑之前,我要求它先把退款相关类的单元测试写完。我给了它一句话:
“请为 RefundService 中所有 public 方法生成单元测试,覆盖率目标 80%。Mock 所有外部依赖,包括数据库、Redis、HTTP 调用。不要遗漏边界条件。”
Claude Code 在 大约 20 分钟内生成了 47 个测试用例。我一个个审查,结果是:
| 质量维度 | 数量 | 占比 |
|---|---|---|
| 直接可用、无需修改 | 32 个 | 68% |
| 需要微调 mock 参数 | 11 个 | 23% |
| 逻辑有问题需要重写 | 4 个 | 9% |
将近 7 成的测试用例零修改通过,这个比例远超我的预期。
更让我惊讶的是,它主动写了几个我没有要求的边界测试:
- “退款金额为 0 时的处理”
- “并发退款请求导致余额不足的场景”
- “支付渠道返回超时时的降级逻辑”
这些测试用例的输入参数和预期行为都和我们的业务规则一致,说明它已经从之前梳理的业务文档中“学到”了业务逻辑。
这 47 个测试用例成了我后面重构的安全网。每次重构一个方法,跑一遍这些测试,绿色通过让我有信心继续。

四、最危险的一次翻车:AI 差点改错了生产退款逻辑
4.1 问题出在哪里
前面说的翻车都是“写错代码”,但至少不会影响生产,因为我们有测试环境和代码审查。但第四次翻车让我真正紧张。
在重构退款计算的核心逻辑时,原来的代码有一个很隐蔽的“补丁式逻辑”:
// 2019年12月新增:针对某大客户的特殊退款规则
if (customerId == 10086 && orderAmount > 100000) {
// 需要人工审核,不走自动退款
return buildManualAuditResult(order);
}
这个逻辑是 2019 年 12 月临时加入的,没有设计文档,常量硬编码,注释也只有一句话。
Claude Code 在分析时,把这段逻辑标注为“疑似死代码,硬编码了客户 ID 和大额阈值,建议用配置代替”。
这个判断从技术角度看没问题,硬编码确实不合理。但它不知道的是:这个客户目前确实是唯一的大客户,而且财务部要求这个逻辑必须是“硬编码不可随意配置”的,因为它涉及合规要求。
如果我当时没仔细审查就直接接受了它的重构建议,把这段逻辑抽成“可配置的规则引擎”,财务部那边会炸锅,因为这意味着可以通过改配置来绕过人工审核。
4.2 我怎么发现并修正的
发现这个问题靠的不是技术经验,而是我对这个项目的业务记忆。我在审查时看到 customerId == 10086,立刻想起来:这是我们公司最大的 B2B 客户,他们的退款要求必须人工审核,这在去年合规审计时被明确要求过。
我立刻给 Claude Code 加了一条约束:
“所有看起来像‘硬编码’但实际上是业务规则或合规要求的逻辑,不要自动改为配置化。请先标记出来让我确认是否是业务约束。”
它在代码里加了一段注释:
// [BUSINESS-RULE-NOTE: 此逻辑为合规要求,不可配置化。详见审计文档 F-2023-047]
if (customerId == 10086 && orderAmount > 100000) {
return buildManualAuditResult(order);
}
这个操作让我意识到一个更深层的问题:AI 缺乏“隐性知识”,那些只存在于某封邮件、某次会议、某个审计要求里的业务背景。它只能从代码本身推断,而代码里没有写“为什么”。
4.3 翻车后的流程改进
这次之后,我调整了和 Claude Code 的协作流程。在每次重构之前,先让它输出一个“重构计划”,专门包含一个章节叫“下列改动涉及业务规则判断,需要人工确认”。然后我逐条确认或驳回,确认之后它才真正开始改代码。
这个流程改动把单次重构时间增加了约 20-30%,但把“危险改动”的比例从大约 12% 降到了 2% 以下。
价值远超成本。

五、我和 Claude Code 的协作模式是怎样进化的
5.1 第一阶段:我当“监工”,它当“苦力”(第 1-2 天)
刚开始的两天,我的使用方式很原始:告诉它“干什么”,然后在结果里挑错。
这个阶段效率不高,而且我很容易在审查时遗漏问题。因为一次性看太多 AI 生成的代码,注意力会涣散。
典型问题:
- 我给的指令太宽泛(“拆分这个类”),导致它做的改动超出了我的预期
- 我没有提前说明约束条件,导致它“好心办坏事”(改了不该改的 public API)
- 我在审查时发现太多问题后,干脆想“还不如我自己写”
反思:不是 AI 不行,是我的使用方式不对。 我需要像对待一个新人同事那样对待它,给清晰的上下文、明确的约束、分步骤执行。
5.2 第二阶段:小步快跑 + 检查点机制(第 3-5 天)
从第三天开始,我调整了策略:
每次重构拆成 3 步:
| 步骤 | 做什么 | AI 负责 | 我负责 |
|---|---|---|---|
| Step 1 | 写测试 | 生成测试用例 | 审查并通过所有测试 |
| Step 2 | 重构代码 | 根据要求改写代码 | 逐行审查 diff |
| Step 3 | 验证 | 跑测试、检查覆盖率 | 确认测试全绿、业务逻辑正确 |
我给每一步设了“检查点”,上一步的产出不合格,绝不进入下一步。
而且,我学会了给 Claude Code 提供“负面清单”:
- 不要改 public API 的签名
- 不要删除任何注释(哪怕看起来过时了)
- 不要引入项目依赖中没有的第三方库
- 不要在重构的同时“顺便优化性能”
这些负面清单极大地减少了“意外”,我不需要每次审查时都重新踩一遍同样的坑。
5.3 第三阶段:AI 主动“告警”,我当“决策者”(第 5-7 天)
到了第五天,我发现 Claude Code 开始表现出一种“主动性”。
在一次重构订单状态机时,它在生成重构方案后,主动标注了一段话:
“我在分析状态流转时发现,
OrderStatus.CLOSED这个状态在代码中有 3 处被赋值,但没有一处把这个状态持久化到数据库。这可能意味着这个状态已经废弃,但也可能是业务逻辑的遗漏。如果是前者,我建议删除相关代码;如果是后者,需要补充持久化逻辑。请确认后我继续。”
这个提醒让我避免了删除一个实际上正在被前端使用(但只在前端做了判断)的状态值。 如果它不提醒,我可能也不会注意到,因为它自己搜不到数据库写入不代表前端没用。
另一次,它在重构退款手续费的逻辑时,发现:
“
calculateFee()方法对计算结果的精度处理不一致:在支付宝分支使用了BigDecimal.setScale(2, HALF_UP),在微信分支使用了BigDecimal.setScale(2, HALF_DOWN)。这可能导致两个渠道在一分钱的舍入上不一致。”
这是一个非常隐蔽的精度 bug,已经存在了 4 年,没有被发现过。AI 在做重构分析时把它揪了出来。
到了这个阶段,我和 AI 的关系从“我指挥它干活”变成了“它给我提供情报,我做出决策”。
5.4 协作模式的本质变化
让我用一个表格总结三个阶段的区别:
| 维度 | 第一阶段 | 第二阶段 | 第三阶段 |
|---|---|---|---|
| 我的角色 | 监工+纠错员 | 定义者+审查者 | 决策者+验证者 |
| AI的角色 | 代码生成器 | 按约束生成+测试 | 分析+告警+生成 |
| 指令粒度 | 模糊目标 | 明确步骤+负面清单 | 目标+边界条件 |
| 信任度 | 每行都要查 | 抽样审查+测试验证 | 聚焦高风险改动 |
| 主要问题 | AI乱改、遗漏 | 需要多轮修正 | AI的告警需要我判断 |
| 效率感受 | 有时不如自己写 | 明显提速 | 放大我的能力 |
核心变化是:我从“代码生产者”变成了“质量决策者”。

六、具体数据:7 天重构的真实效果
6.1 代码量化指标
重构结束后的统计(全部由 SonarQube 和 Git 统计得出):
| 指标 | 重构前 | 重构后 | 变化 |
|---|---|---|---|
| 核心模块代码行数 | 42,380 | 28,470 | 减少 33% |
| 最大单文件行数 | 3,742 | 687 | 减少 82% |
| 平均方法行数 | 74 | 28 | 减少 62% |
| 单元测试覆盖率 | 8% | 71% | 提升 63 个百分点 |
| 注释覆盖率 | 2.7% | 14% | 提升 11.3 个百分点 |
| 循环依赖数 | 7 | 0 | 全部消除 |
| SonarQube 主要问题数 | 312 | 44 | 减少 86% |
最让我欣慰的不是代码行数少了,而是最大方法从 840 行降到了 95 行。 这意味着下一个接手的人,不用再面对一个“地狱级”的方法了。
6.2 效率对比数据
这是我最关心的数据:AI 到底省了多少时间?
我记录了每次重构任务的耗时,并对比了我预估的“纯人工”时间:
| 重构任务 | 人工预估时间 | AI 辅助实际耗时 | 其中我的有效工作时间 |
|---|---|---|---|
| 梳理业务逻辑 | 5 天 | 1 天 | 7 小时 |
| 补充单元测试(220个用例) | 10 天 | 2.5 天 | 18 小时 |
| 拆分 OrderService | 2 天 | 2.5 小时 | 2.5 小时 |
| 重构退款逻辑 | 3 天 | 1 天 | 7 小时 |
| 消除循环依赖 | 2 天 | 3 小时 | 3 小时 |
| 去除硬编码配置 | 1 天 | 2 小时 | 2 小时 |
| 代码审查和回归验证 | 5 天 | 2 天 | 14 小时 |
| 总计 | 28 天 | 约 7.5 天 | 约 53.5 小时 |
从 28 人天降到 7.5 天(以我为主力 + 兼职 Review 同事),效率提升约 3.7 倍。
但请注意:“我的有效工作时间”这一列不是 7.5×8=60 小时,而是 53.5 小时,因为 AI 在做代码生成和分析时,我有一部分时间是在等待或者做其他事情。实际我的注意力投入约 53.5 小时,比纯人工节省了约 75% 的时间。
6.3 但成本不只是时间
除了时间,还需要计算其他成本:
| 成本项 | 详情 |
|---|---|
| Claude Code API 费用 | 约 $47(7 天累计 token 消耗) |
| 学习成本 | 前 2 天效率很低,试错花了大约 8 小时 |
| 同事 Review 时间 | 约 10 小时(主要审查高风险改动) |
| 风险溢价 | 如果不走测试 → 预发 → 灰度流程,引入的 bug 可能造成线上事故 |
如果算上学习成本和 Review 成本,第一次用 AI 重构并没有“立刻盈利”。但这是一次性投入,下次再用,前 2 天的试错时间可以节省 80% 以上。

七、这类工具在遗留代码重构中的真实适用边界
7.1 什么场景下 Claude Code 特别好用
经过这 7 天的实战,我总结出 4 个 Claude Code 效果最好的场景:
1. 理解并梳理屎山代码的业务逻辑
这是 AI 最让我服气的能力。它能在几分钟内扫描数百个文件,梳理出方法调用链、数据流向、状态机变化。这对人类来说是最痛苦、最耗时、最容易遗漏的工作。
2. 补充单元测试
我愿称之为“测试生成神器”。虽然会有约 10% 的测试需要重写,但另外 90% 能节省大量时间。特别是边界条件测试,AI 的想象力比人更全面。
3. 识别代码中的风险模式和隐藏 bug
前面提到的精度不一致、空指针风险、事务遗漏,都是 AI 在分析过程中主动发现的。这相当于一个 7×24 工作的资深 Code Reviewer。
4. 执行“有明确规则”的重构
比如:拆分大类、提取公共方法、用配置替代硬编码、策略模式替换 if-else。这些重构有清晰的“输入-输出”规则,AI 执行质量很高。
7.2 什么场景下效果打折
1. 涉及“隐性业务知识”的改动
前面的大客户退款规则就是典型。代码里看不到“为什么”,只有“怎么做”。AI 会把它当成普通的硬编码来处理,从而产生危险的建议。
2. 对性能有极致要求的优化
我试过让 Claude Code 优化一个慢 SQL,它给的方案是“加索引”。但我需要的是“重新设计查询逻辑以减少 JOIN”,它不理解数据库表的实际数据量分布和索引选择性,无法做出准确的性能判断。
3. 架构级别的决策
比如:要不要把订单系统拆成微服务?要不要引入事件溯源模式?这类问题涉及组织架构、团队能力、未来业务方向,AI 只能给出教科书式的答案,没有实际决策价值。
4. 需要“创造性设计”的场景
在重构支付路由逻辑时,我需要设计一个能支持“动态增加支付渠道+渠道权重分配”的架构。Claude Code 给出了一个中规中矩的策略模式方案,但我想要的是一种更灵活的“责任链+规则引擎”混合模式。AI 倾向于给出最主流、最安全的解,而不是最具创新性的解。
7.3 一个实用的“要不要用 AI”决策框架
我把自己的判断逻辑总结成一个简单的决策表:
| 任务特征 | AI 适用度 | 建议使用方式 |
|---|---|---|
| 规则明确、步骤固定 | ⭐⭐⭐⭐⭐ | 直接交给 AI,人工审查结果 |
| 需要理解大量现有代码 | ⭐⭐⭐⭐⭐ | AI 做分析,人做决策 |
| 需要生成大量样板代码/测试 | ⭐⭐⭐⭐⭐ | AI 生成,人工审查关键逻辑 |
| 涉及隐性业务知识 | ⭐⭐ | AI 先标记可疑点,人确认后再改 |
| 需要性能调优 | ⭐⭐ | AI 辅助分析,人做最终优化 |
| 需要架构决策 | ⭐ | 可以参考 AI 建议,但必须人决策 |

八、给想用 Claude Code 重构遗留代码的人的实战建议
8.1 开始之前必须做的 3 件事
第一:先建立安全网。
在没有测试的情况下用 AI 重构,等于闭着眼睛开车。哪怕只写 10 个核心流程的回归测试,也比裸奔强。我的建议是:让 AI 帮你写第一版测试,但你必须理解并运行通过它们。
具体步骤:
- 选择 5-10 个最核心的业务流程(下单、支付、退款等)
- 让 Claude Code 为每个流程生成 3-5 个测试用例
- 审查测试用例的逻辑正确性
- 跑通并设为 CI 的必过项
第二:先让 AI 读代码,不要急着让它写代码。
我花了一整天让 Claude Code 分析和梳理业务逻辑,这看起来很“浪费”,但后来证明是最值的投入。因为:
- 你借此确认 AI 对项目的理解是否正确
- AI 在分析过程中已经建立了对项目的“心智模型”
- 你得到的分析文档本身就很有价值
第三:准备好“负面清单”。
在让 AI 动手改代码之前,把你绝对不能接受的事情写清楚:
- 不能改的 API 有哪些
- 不能动的配置有哪些
- 不能删除的逻辑有哪些
- 不能引入的第三方库有哪些
这减少了至少 50% 的“意外”。
8.2 重构过程中的 4 条铁律
铁律 1:小步快跑,一次只改一个类
我在第二天犯过“一次让 AI 重构 3 个关联类”的错。生成的代码 diff 有 800 多行,审查到一半我就放弃了,太多改动点,注意力完全跟不上。
后来我规定:每次只重构一个类,diff 不超过 300 行。 虽然拆分步骤多了,但审查质量大幅提升。
铁律 2:每个改动必须对应一个通过的测试
如果 AI 改了 RefundService.refund(),那在合并代码之前,RefundServiceTest 里的所有测试必须全绿。不绿就不合。
铁律 3:AI 引入的所有外部 API 调用必须验证
前面的 WechatPayUtils.decryptNotify 翻车教会了我这件事。现在我要求 Claude Code 在引入新 API 时,用注释标注出它来自哪个依赖的哪个版本。然后我手动确认。
铁律 4:涉及钱的逻辑必须人工二次审查
支付、退款、优惠券计算,这些逻辑里任何一个 bug 都是直接的经济损失。AI 生成的这些代码,我全部逐行审查了两遍,一次看逻辑,一次看边界条件。
8.3 如何和 Claude Code 更好地“沟通”
经过 7 天的磨合,我总结出一些实用的 Prompt 技巧:
1. 给上下文,不要只给指令
❌ 差的 Prompt:
“重构 OrderService,让它更简洁”
✅ 好的 Prompt:
“OrderService 有 3700 行,职责混杂,同时处理查询、命令、退款。请将其拆分为 3 个类:QueryService(读操作)、CommandService(写操作)、RefundService(退款专用)。需保持所有 public 方法签名不变。不要引入新的第三方依赖。”
2. 明确“不要做什么”比“要做什么”更重要
❌ 只说:
“优化这段代码”
✅ 加上:
“优化这段代码。但不要:改动 public 方法签名、删除任何注释、引入 lambda 表达式(项目要求 Java 8 兼容)、修改 SQL 查询逻辑。”
3. 当 AI 犯错时,给它看证据
❌ :
“你写的这段不对”
✅ :
“你生成的
decryptNotify方法在我们的WechatPayUtils中不存在。请搜索项目中的实际解密实现,用真实的方法替换。错误证据:[截图/报错信息]”
4. 要求它“先计划,再执行”
对于复杂任务,我会在 Prompt 结尾加一句:
“请先给出重构计划,列出每一步的改动范围,等我确认后再执行。”
这样就避免了“它闷头改了一堆,你审查到一半想全部推翻”的尴尬。
8.4 团队环境下使用 AI 重构的额外建议
如果你的团队不止你一个人在用 AI 重构代码,我还有几点建议:
| 建议 | 原因 |
|---|---|
| 建立团队的“AI 使用约定” | 避免每个人用不同风格,导致代码库风格分裂 |
| AI 生成的代码必须在 PR 中标记 | 让 Reviewer 知道这些代码需要额外关注 |
| 定期回顾 AI 引入的 bug | 建立“AI 常见犯错清单”,提高审查效率 |
| 不要把 AI 当“黑盒”来吹 | 如果你用 AI 写代码但不好意思说,那可能有问题。透明化是质量保证的基础 |

九、当我习惯 AI 重构后,心态上的变化
9.1 从“我怕自己变懒”到“我可以更专注”
第一周我在使用 Claude Code 时,心里有一种隐隐的不安:“我是不是在偷懒?如果所有东西都交给 AI 写,我的技术能力会不会退化?”
但到了第七天,我的想法变了。
因为我在审查 AI 生成的代码时,能明显感觉到:我花在“理解业务”和“做判断”上的时间更多了,花在“敲代码”上的时间更少了。 以前写一个重构方案,我 60% 的时间在处理细节(依赖关系、方法签名、测试用例),只有 40% 的时间在思考“这么改对吗”。现在 AI 帮我处理了细节,我 80% 的时间在决策。
我没有变懒,我只是从“一线工人”变成了“质检工程师+架构师”。
9.2 对 AI “认错”和“坚持”的感受
有一件事让我至今记忆犹新。
在重构订单状态机时,Claude Code 坚持认为某个状态转换逻辑存在逻辑漏洞。我一开始不认同,告诉它“这个逻辑我们已经跑了三年,不可能有问题”。
它没有直接认错,而是列出了一组具体的参数组合,证明在这个组合下,状态机会进入一个不可达的分支。
我仔细验证后,发现它说对了,只是这个参数组合在过去三年里恰好没有出现过。
这一刻我突然意识到:AI 不是在“挑战”我,它是在用它的方式帮我发现我因为“经验自信”而忽略的盲区。 它的价值不在于“听话”,而在于“不迷信我的判断”。
9.3 最让我警惕的一件事
但我也必须承认一件事:这种协作方式让我和代码之间多了一层距离。
以前我自己写代码,对每一行都有“体感”。现在 AI 生成了 80% 的代码,我审查了、测试了、验证了,但那种“每一行都是我写的”的掌控感确实减弱了。
这不是坏处,但需要习惯。我需要学会在“信任 AI”和“保持质疑”之间找到平衡。
我现在给自己的要求是:
- 核心业务逻辑(支付、退款、库存)坚持逐行审查
- 样板代码和工具方法信任 AI 会处理好
- 每个 PR 合入前,我必须在心里过一遍:“如果有人问我这段代码为什么这么写,我能解释清楚吗?”
十、总结:别把 Claude Code 当魔法棒,把它当搭档
7 天,12 个文件,220 个测试用例,代码减少 33%,测试覆盖率从 8%到 71%。
这个结果让我满意,但我更想说的是这些数字背后的事情。
Claude Code 没有让我变成一个“不用写代码的程序员”。它让我变成了一个“把更多时间花在理解业务、做判断、做决策上的程序员”。
如果你问我,用 Claude Code 重构遗留代码是一种什么感觉。我会说:
像是突然多了一个特别能干活、但需要你持续把关的新同事。它能帮你处理掉所有“高重复低价值”的工作,但所有涉及“判断”和“决策”的事情,责任还是在你身上。它不会取代你,但它会放大你的能力,前提是你知道怎么用好它。
最后,给想尝试的人三条最实用的建议:
- 别急着让它写代码,先让它读代码。 理解成本是重构的最大成本,把这部分交给 AI。
- 建立安全网再动手。 没有测试的重构不是重构,是改造事故。
- 保持质疑。 AI 会创造出看起来很合理但根本不存在的 API,会把你三年没遇到的问题挖出来,也会因为你没说清楚而好心办坏事。你的判断力,是和 AI 协作中最不可替代的资产。
这 7 天的重构经历让我相信一件事:未来优秀的程序员,不是写得最快的,而是最擅长和 AI 对话、审查 AI 输出、判断 AI 建议的。
那个只会埋头敲代码的时代,可能真的要过去了。
*注:本文所有数据来自我 2024 年 5 月的一个实际项目重构记录。项目为内部系统,部分业务细节和客户信息已脱敏处理。Claude Code 使用 Anthropic 官方 API,版本为 2024 年 4 月发布的最新版。API 费用按照实际账单记录,不包含试验和对话过程中的无效消耗。*
常见问题解答(FAQ)
1. Claude Code 重构遗留代码时,如何解决它看不懂项目全貌的问题?
我试过让 Claude Code 直接读一个几百行的旧函数,它给出的重构建议经常跑偏,像是只看了局部就瞎猜全局。我很困惑:是不是我的提示词写得不够好?或者有办法让 Claude Code 真正理解整个项目的上下文?
我用过一个真实的 Spring Boot 遗留项目,代码 3000+ 行,没有单元测试、没有 Swagger 文档。第一次尝试时,我把整个 Controller 文件丢给 Claude Code,让它“重构成整洁架构”,结果它生成了一个完全忽略了数据库事务和 Redis 缓存的版本。
翻车之后我调整了策略:先分步喂项目结构,先给 pom.xml 和 application.yml 说明依赖,再给出核心实体类和 Repository 接口,最后才给业务逻辑代码。每次对话都加一句限制:‘不要动数据库层和缓存层的代码逻辑,只重构 Service 层的条件判断和异常处理’。
这样分批喂上下文,Claude Code 的准确率从 40% 提升到了 85%。我的判断是:它不是看不懂项目,而是我们假设它能一次吞下所有上下文,但它对遗留代码的‘暗逻辑’其实是零了解,那些没有写在代码里的业务规则,它只能靠猜。
所以我的建议是:每次限定重构范围,并且先用测试用例约束行为,再让 AI 动手。
2. 用 Claude Code 重构后,如何快速验证它没引入隐藏 Bug?
我试过用 Claude Code 重构了一个 500 行的订单模块,跑完单元测试都是绿的,但上线后发现一个极隐蔽的并发问题,它把 synchronized 块内部的锁对象换成了局部变量。
我之前太信任测试覆盖率了,现在想知道:除了写更多单元测试,有没有更高效的验证方法,帮我提前发现 AI 重构后的隐藏坑?
我踩过一模一样的坑。那次重构的是 Python 的 Flask 项目,Claude Code 把一段用 threading.Lock() 控制并发的代码改成了 asyncio.Lock,但项目本身是同步的,导致生产环境频繁报错。
我事后总结了一套三步验证法:第一,对每个重构后的文件用 diff 工具(如 git diff 或 Beyond Compare)逐行对比,重点看 AI 自己加的注释或改动中那些‘看起来太完美’的部分,AI 容易过度优化,比如把显式循环改成列表推导式但忘了处理 StopIteration。
第二,用 mutation testing 工具(例如 pytest-mutpy)增加测试的变异覆盖率,看 AI 改后的代码能否杀死所有变异体。我那次花 30 分钟跑完变异测试,发现了 7 个未被单元测试覆盖的边界条件。
第三,在 staging 环境用流量回放工具(如 GoReplay 或 mitmproxy)直接回放生产环境请求,观察重构前后响应是否一致。这套流程下来,后续重构再也没有出现线上事故。
3. Claude Code 和 Cursor/Copilot 相比,重构遗留代码到底强在哪?
市面上有很多 AI 编程工具,Cursor、GitHub Copilot 我都在用,但它们在处理遗留代码时的表现差别很大。Copilot 辅助写新代码很快,但重构老代码时经常给出不符合现有风格的代码。我想知道 Claude Code 在理解和重构遗留代码方面,有没有真正的不可替代的优势?
我同时订阅了 Claude Code、Cursor 和 GitHub Copilot,并在同一个遗留项目(Java + JSP 混合的老系统)上做了对比测试。结论是:Claude Code 在“多文件因果推理”上具有显著优势。
具体数据:给每个工具同样的任务,把 JSP 中嵌入的 Java 脚本片段重构为独立的 Service 类。Copilot 只能给出片段建议,无法理解 JSP 中 Session 变量的生命周期;Cursor 的 agent 模式能跨文件搜索,但经常给出未导入的包。
Claude Code 则可以在一次对话中跟踪 8-10 个文件之间的依赖关系,并能主动提问(例如‘我看到 userToken 是从 Session 中取的,是否需要保持 HttpSession 引用?’)。这种主动澄清的能力大大减少了理解偏差。
但 Claude Code 也有弱点:它的代码补全速度比 Copilot 慢 3-4 倍,适合深思熟虑的重构,不适合快速编写样板代码。所以我的建议是:重构遗留代码时,先用 Claude Code 做整体方案设计和多文件修改,再用 Copilot 补零碎的 getter/setter 和测试数据。
4. Claude Code 重构遗留代码的成本和隐私问题怎么权衡?
Claude Code 调用 API 是按 token 计费的,重构一个稍大的项目很容易花几十美元。我的项目涉及客户个人信息,代码上传到 Anthropic 服务器总有点不放心。我想知道有没有既控制成本又确保数据安全的实践方法,或者 Claude Code 有没有提供离线版本?
我重构的遗留项目刚好是医疗数据平台,代码中有大量敏感字段名(如 patient_ssn、diagnosis_code)。
我的做法是:第一,使用 Claude Code 的‘项目级别’上下文压缩功能(Claude Code 在初始化项目时可以选择‘摘要模式’,它会自动将整个代码库的关键点提取成一份 2000 字的 markdown 文件,而不上传原始代码)。
第二,对于需要 AI 理解具体业务逻辑的函数,我会先手动替换敏感变量名为无害的占位符(如 $FIELD1、$FIELD2),在本地做一个占位符-真实字段的映射表。重构完成后再按映射替换回来。这样上传的代码不包含真实业务信息。
第三,成本控制方面:一次完整的重构(约 5000 行 Java 代码)花费了大约 15 美元的 API 费用(使用 Claude 3.5 Sonnet)。我用了分层策略:只对最混乱的 20% 的代码(约 1000 行)使用 Claude Code 进行深度重构,其余部分用本地规则和脚本自动格式化。
这样成本降低了 80%。我的判断是:对于绝大多数中型项目,Claude Code 的成本远低于让一个人工工程师从头重写相同代码的人力成本,但隐私保护必须提前规划,不能完全信任云服务商。
核心关键词
文章版权归“万象方舟”www.vientianeark.cn所有。发布者:程, 沐沐,转载请注明出处:https://www.vientianeark.cn/p/600221/
温馨提示:文章由AI大模型生成,如有侵权,联系 mumuerchuan@gmail.com 删除。
读者评论
看完了,太真实了。特别是那个processRefund方法840行,注释不到3%,简直是我司系统的写照。之前我们也尝试过手动重构,每次都以失败告终,因为你永远摸不清哪根线会扯出什么bug。作者把重构前的风险评估和与AI的“对齐”过程写得很清楚,没有吹嘘一键搞定,这种诚实很难得。先让AI梳理业务而不是直接改代码,这招学到了。
以前觉得Cursor够用了,看完才知道在复杂项目里Claude Code的跨文件追踪有多重要。作者对比时那个“饭可能在厨房里”的比喻笑死我了,但确实点到要害。长上下文理解是重构遗留代码的核心,不然连调用链都理不清。我也准备拿公司的老订单系统试一试,不过肯定会先建好测试,作者踩的坑就是警示。
翻车翻得真实。改public方法签名被作者叫停那段,像极了刚入职的新人热情过度又不懂业务边界。AI确实聪明,但项目里那些“不能动”的潜规则它不知道,得靠人把关。文章把重构描述成一场需要不断纠正和对齐的对话,而不是伸手要代码,这种认知对我帮助很大。以后用AI,我会更注重设定约束条件。
个工作日,代码量砍掉33%,测试覆盖率从8%飙到71%,这个数据很有说服力。但更打动我的是成本估算部分,手动重构要30-40人天,AI辅助砍到一半。对于资源紧张的团队来说,这种ROI是实实在在的。不过作者强调必须有人Review和测试,否则就是埋雷。打算先用小模块试试水,验证一下这个模式。
文章最有价值的是那31条风险点清单和生成文档的部分。很多AI教程只讲怎么出代码,不讲怎么让AI帮你理解烂代码。作者让Claude Code梳理业务逻辑、识别并发和事务缺失,这本身就是巨大的产出。即使最后不直接用AI改代码,这些分析也能帮团队快速接手项目。已收藏,准备下次重构前先走一遍这个流程。
最后和AI“谈判”的部分让我感触最深。Claude Code想按最佳实践改签名,作者坚守接口不变的原则,这才是真实的工程决策。不是技术最优就行,还得考虑兼容性、工期和风险。文章没有神话AI,反而把人的判断力放在了第一位。对于还在犹豫要不要用AI重构的人来说,这篇是很好的参考,既给了信心也给了警醒。