记录一次用 claude code 重构遗留代码的真实体验

记录一次用 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 之前,我做了三个判断:

  1. 不能全量重写:业务方不会接受“停下手头需求,让我们重构三个月”。必须在保持功能正常的前提下逐步替换。
  2. 必须建立安全网:没有测试的重构就是裸奔。无论如何,先要有基本的回归测试。
  3. 理解业务逻辑是最大成本:AI 能帮我写代码,但它需要我来告诉它“这段代码要干什么”,而我自己也得搞清楚。

我当时记了一笔账:

如果人工重构,预计需要 2 个后端 + 1 个测试,投入 6-8 周,总成本约 30-40 人天。

如果让 AI 辅助,我作为主力 + 另一个同事 Review,预计 2-3 周,总成本约 12-15 人天。

但前提是:AI 真的能理解这套烂代码。

记录一次用 claude code 重构遗留代码的真实体验

二、为什么选 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 个引用文件。退款流程涉及以下路径:

  1. OrderController.refund() 接收请求,调用 OrderFacade.refundApply()
  2. OrderFacade 做了状态校验(但缺少并发锁控制)
  3. 实际的退款计算在 OrderServiceImpl.processRefund() 第 847-1120 行
  4. 这个方法有 3 个嵌套的 if-else 分支,分别处理‘全部退款’‘部分退款’‘运费补贴’
  5. 我发现第 1023 行有一个潜在的空指针风险:代码先调用了 order.getPayChannel().getRefundRate(),但没有判断 payChannel 是否为空。”

这个对比说明了核心差异:

  • Copilot / Cursor 擅长行级补全和当前文件理解
  • Claude Code 能跨文件追踪调用链、识别隐藏的依赖关系、发现潜在的 bug

记录一次用 claude code 重构遗留代码的真实体验

2.2 第一个测试:让 Claude Code 给我讲一遍业务

正式开始重构前,我做了个试验。我在项目根目录下启动 Claude Code,给了它这样一段 prompt:

“这是我们的订单系统,核心目录在 order-module 下。请你在不修改任何代码的前提下,帮我梳理以下几个问题:

  1. 退款流程的完整调用链路是怎样的?
  2. 有哪些地方可能出现并发问题?
  3. 哪些方法缺少必要的事务注解?”

Claude Code 花了大约 4 分钟扫描代码(项目约 400 个 Java 文件),然后给出了回答。我把它梳理的结果和我知道的情况做了对比:

检查项 Claude Code 发现 我的验证结果
退款调用链 准确,8 个关键节点 正确
并发风险点 指出 4 处 其中 3 处确实存在,1 处因为上游做了分布式锁,误报
缺少事务注解 指出 11 处方法 我确认其中 8 处确实需要加 @Transactional
死代码 指出 3 段无法到达的代码 全部正确,其中一段是 2019 年的灰度逻辑

这个试验让我建立了基本信任:它能读懂项目,但不是 100% 准确。我需要验证它的每一个判断。

2.3 关键决策:不让 AI 直接写代码,先让它写分析文档

基于上面的试验,我做了一个后来证明非常正确的决定:第一轮对话不让 AI 改任何代码,只让它生成重构分析和测试用例。

这样做有两个好处:

  1. 我和 AI 先对齐“对业务的理解”,避免它在错误的理解上写代码
  2. 生成的测试用例可以作为安全网,后续改代码时有保障

我让 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 比自己写更快,而是因为它承担了“找出所有依赖关系、把代码归位、生成对应的单元测试”这些高强度低创造性的工作。 我做的更多是“审查和决策”。

记录一次用 claude code 重构遗留代码的真实体验

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 个测试用例成了我后面重构的安全网。每次重构一个方法,跑一遍这些测试,绿色通过让我有信心继续。

记录一次用 claude code 重构遗留代码的真实体验

四、最危险的一次翻车: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 重构遗留代码的真实体验

五、我和 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的告警需要我判断
效率感受 有时不如自己写 明显提速 放大我的能力

核心变化是:我从“代码生产者”变成了“质量决策者”。

记录一次用 claude code 重构遗留代码的真实体验

六、具体数据: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% 以上。

记录一次用 claude code 重构遗留代码的真实体验

七、这类工具在遗留代码重构中的真实适用边界

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 重构遗留代码的真实体验

八、给想用 Claude Code 重构遗留代码的人的实战建议

8.1 开始之前必须做的 3 件事

第一:先建立安全网。

在没有测试的情况下用 AI 重构,等于闭着眼睛开车。哪怕只写 10 个核心流程的回归测试,也比裸奔强。我的建议是:让 AI 帮你写第一版测试,但你必须理解并运行通过它们。

具体步骤:

  1. 选择 5-10 个最核心的业务流程(下单、支付、退款等)
  2. 让 Claude Code 为每个流程生成 3-5 个测试用例
  3. 审查测试用例的逻辑正确性
  4. 跑通并设为 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 写代码但不好意思说,那可能有问题。透明化是质量保证的基础

记录一次用 claude code 重构遗留代码的真实体验

九、当我习惯 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 重构遗留代码是一种什么感觉。我会说:

像是突然多了一个特别能干活、但需要你持续把关的新同事。它能帮你处理掉所有“高重复低价值”的工作,但所有涉及“判断”和“决策”的事情,责任还是在你身上。它不会取代你,但它会放大你的能力,前提是你知道怎么用好它。

最后,给想尝试的人三条最实用的建议:

  1. 别急着让它写代码,先让它读代码。 理解成本是重构的最大成本,把这部分交给 AI。
  2. 建立安全网再动手。 没有测试的重构不是重构,是改造事故。
  3. 保持质疑。 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 的成本远低于让一个人工工程师从头重写相同代码的人力成本,但隐私保护必须提前规划,不能完全信任云服务商。

核心关键词

读者评论

王安宁

看完了,太真实了。特别是那个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重构的人来说,这篇是很好的参考,既给了信心也给了警醒。

文章版权归“万象方舟”www.vientianeark.cn所有。发布者:程, 沐沐,转载请注明出处:https://www.vientianeark.cn/p/600221/

温馨提示:文章由AI大模型生成,如有侵权,联系 mumuerchuan@gmail.com 删除。
(0)
用 claude code 自动生成代码注释的最佳实践争议
上一篇 8分钟前
claude code 处理多语言混合项目时的策略选择
下一篇 8分钟前

相关推荐

  • claude code 处理多语言混合项目时的策略选择

    十几年的研发生涯里,我处理过的多语言混合项目不下四十个。从最早的一个 Java 后端带着 Perl 脚本、夹杂两万行 shell 配置的烂摊子,到后来 Go+Python+Rust 三语并行的微服务集群,每一次我都发现同样的问题:团队把多语言当成技术挑战去解决,却很少意识到它本质上是一个组织策略问题。 去年我把 Claude Code 引入到一套 Python 后端 + TypeScript 前端…

    8分钟前
    000
  • 将 claude code 集成到本地开发环境的不同配置路径

    将 claude code 集成到本地开发环境的不同配置路径 上个月,我帮助一家中型 SaaS 公司的 DevOps 团队解决了一个棘手问题:整个团队 20 多个开发者,同一周内有 7 个人因为 Claude Code 环境配置不一致导致代码审查冲突。有人在 Windows 的全局安装上跑了 3 天才发现 Node.js 版本不对,有人在 WSL 和宿主 Windows 之间反复切换导致 API …

    8分钟前
    000
  • 用 claude code 自动生成代码注释的最佳实践争议

    用 claude code 自动生成代码注释的最佳实践争议 过去六个月,我在三个项目里深度使用了 Claude Code 的自动注释功能。第一次是在一个支付系统的重构项目里,第二次是在一个 SaaS 平台的组件库迭代中,第三次是带一个五人团队从零搭建新的数据中台。 三次体验下来,我得出了一个让很多人不舒服的结论:自动生成注释这项功能,在它最被吹捧的那些场景里,恰恰是最危险的存在。 不是因为技术不行…

    8分钟前
    000
  • claude code 在快速原型验证阶段的实用价值

    去年第四季度,我们团队接了一个供应链 SaaS 的 MVP 项目。客户给的时间窗口是 7 个工作日,要求交付一个可交互的库存调度原型,用于向投资人做现场演示。传统做法是产品经理出线框图、设计师出高保真、前端开发切页面、后端开发搭接口,四步下来,两周起步。但当时我们只剩一个人力,就是我。 我用了三天,完成了从需求梳理到可点击原型的全部过程。不是因为我效率高,是因为我把 Claude Code 当成了…

    8分钟前
    000
  • claude code 生成复杂算法时的输出稳定性评估

    Claude Code 生成复杂算法时的输出稳定性评估 “它第4次给出的答案是对的,但第5次又错了。” 这是我在用 Claude Code 写一个带状态的动态定价算法时,盯着终端屏幕的真实感受。同一个 Prompt,跑了 12 次,正确率只有 58%。不是模型不懂动态规划,它甚至能在第 3 次输出几乎教科书级的带备忘录递归实现。但第 6 次,它突然在状态转移方程里少了一个边界判断,导致价格在临界点…

    8分钟前
    000
站长微信
站长微信
分享本页
返回顶部