实战:安全重构
Claude Code 安全重构教程:重构最容易失控,要先要求 CC 保持行为不变,再小步修改、小步验证和审查 diff。
重构前计划
重构不是“看起来更优雅”就能做。让 CC 重构前,必须先证明:为什么要重构、保持哪些行为不变、怎么验证行为没变。
/plan 请评估这次重构是否必要,不要修改文件。 重构目标: 【写清楚为什么要重构】 请输出: 1. 当前代码的问题。 2. 是否可以不重构也解决。 3. 最小重构范围。 4. 需要保持不变的行为。 5. 验证方式。 6. 风险点。
适合重构的情况
- 代码重复导致同一个逻辑要改多处。
- 函数太长,已经影响理解和测试。
- 命名混乱,导致后续修改容易改错。
- 同一模块里职责混在一起,但可以小步拆开。
- 已经有测试或明确验收方式能证明行为不变。
重构的合理目标应该能被验证。例如:
| 合理目标 | 可验证方式 |
|---|---|
| 提取重复逻辑 | 重复代码减少,原测试通过 |
| 拆分长函数 | 输入输出不变,调用方不变 |
| 改善命名 | 行为不变,diff 只涉及命名 |
| 拆出组件 | 页面展示和交互不变 |
不适合现在重构的情况
- 需求还不稳定,业务逻辑随时会变。
- 当前没有测试,也没有可执行验收方式。
- 正在修紧急 Bug,不应该混入结构调整。
- 涉及数据库、权限、支付、登录等高风险路径。
- CC 的计划里出现“顺便全局优化”。
如果当前任务是紧急修 Bug,先修 Bug,再单独开重构任务。不要把“救火”和“整理代码”混在一起。
重构风险分级
| 重构类型 | 风险 | 建议 |
|---|---|---|
| 改命名 | 低到中 | 确认引用和测试 |
| 提取函数 | 中 | 保持输入输出不变 |
| 拆组件 | 中 | 检查页面展示和交互 |
| 改模块边界 | 高 | 分步做,先有测试 |
| 改数据流 | 高 | 审查接口和状态变化 |
| 改权限或数据库 | 极高 | 不和普通重构混做 |
执行限制
可以做最小安全重构。 要求: 1. 保持外部行为不变。 2. 不要同时加新功能。 3. 不要顺手格式化无关文件。 4. 每个修改都说明为什么必要。 5. 修改后运行相关检查或说明无法检查的原因。
小步重构节奏
请把重构拆成小步执行。 要求: 1. 每一步只改一个结构问题。 2. 每一步都保持外部行为不变。 3. 每一步完成后说明 diff。 4. 如果项目有测试,每一步后运行相关测试。 5. 如果没有测试,每一步给出人工验收方法。 6. 不要在重构中新增功能。
每一步完成后先停一下
这一步重构完成后先暂停。 请说明: 1. 这一步解决了哪个结构问题。 2. 是否保持外部行为不变。 3. 修改了哪些文件。 4. 是否运行了检查。 5. 是否建议继续下一步,还是先验收。
重构前建立保护网
如果项目有测试,先跑相关测试;如果没有测试,至少让 CC 写出人工验收路径。
在重构前,请先建立保护网。 要求: 1. 找到现有测试或检查方式。 2. 如果没有测试,列出人工验收步骤。 3. 说明哪些行为必须保持不变。 4. 标出高风险路径。 5. 在保护网不清楚前,不要开始重构。
行为不变怎么证明
- 输入一样,输出一样。
- 页面展示和交互一样。
- 接口字段和错误码一样。
- 数据读写结果一样。
- 已有测试仍然通过。
- 用户流程没有变化。
让 CC 明确写出来:
请列出本次重构必须保持不变的行为。 格式: 1. 输入: 2. 输出: 3. 用户可见行为: 4. 接口兼容性: 5. 错误处理: 6. 验证方式:
不要把重构包装成功能
如果重构过程中发现新功能需求,先放到后面:
这个新需求不属于本次重构。 请把它记录为后续任务: 1. 新需求是什么。 2. 为什么不应该混入重构。 3. 如果以后做,应该如何单独验收。
发现重构范围变大时
先暂停重构。 请重新评估: 1. 已经改了哪些文件。 2. 哪些改动是必要的。 3. 哪些改动可以撤回或拆到下一次。 4. 当前是否仍然保持行为不变。 5. 是否建议停止在当前安全边界。
重构后的验收模板
请验证这次重构。 请输出: 1. 重构前后外部行为是否一致。 2. 修改了哪些文件。 3. 每个文件为什么必须改。 4. 跑了哪些测试或检查。 5. 没有验证到的风险是什么。 6. 是否可以进入 /code-review。
重构收尾判断
请给出重构收尾判断。 请回答: 1. 是否实现了重构目标。 2. 是否有行为变化。 3. 是否有未验证风险。 4. 是否还需要继续重构。 5. 如果继续,是否应该单独开新任务。
验收结果
- 行为没有变化。
- 改动范围被控制住。
- 没有把重构和新功能混在一起。
- 每一步都有验证或人工验收方式。
- 重构前有保护网,重构后能证明行为不变。