纪律解决什么问题
重构的风险通常不来自改法本身,而来自失控的步子:一次改十几个文件、跳过测试、顺手修缺陷,红灯出现时就无法判断是哪一步引入的。安全重构靠的是可重复的流程:小步改动、每步保持可编译可运行、提交粒度小、重构与行为变化分离、随时能退回已知良好状态。
基本信息
| 适用场景 | 既有代码结构整理、坏味道消除、接手遗留模块 |
|---|---|
| 前提 | 有可运行测试;没有则先补行为基准测试 |
| 节奏 | 小步快跑,每一步都必须绿灯 |
| 分离 | 重构提交不含行为变化,行为变化另开提交 |
| 止损 | 任何一步失控立即退回上一步,而不是在红灯上继续叠加 |
一次重构的标准循环
- 选定一个坏味道作为本轮目标,一次只处理一个。
- 行为测试缺失时先补:用当前输出作为断言基准,先绿再改。
- 执行最小改动;IDE 有自动化重构命令就直接用,减少手改面。
- 立刻运行测试与编译:绿灯才提交,红灯就回退该步。
- 提交保持小而完整,提交信息写清这一步做了什么。
- 一轮结束后回看整体结构,再决定是否继续下一轮。
循环的分步要点
循环的分步要点
# 1. 明确这一步的目标:只消除一个坏味道
# 2. 缺测试先补行为测试(断言当前行为,先跑绿)
# 3. 最小改动:优先用 IDE 的自动重构,手改越少越好
# 4. 立即跑测试与编译,绿灯才提交
# 5. 红灯回退该步,不要在红灯上继续叠加改动
# 6. 重构与功能改动分属不同提交,便于二分定位纪律与违反后果
| 纪律 | 违反后的表现 |
|---|---|
| 小步推进 | 改动跨十几个文件,问题定位成本成倍上升 |
| 每步绿灯 | 先改完再跑测试,错误堆叠、原因难分 |
| 与功能分离 | 行为变化与结构调整交织,评审与回滚都变难 |
| 提交粒度小 | 回滚牵连无关改动,热修时间被拉长 |
| 测试先行 | 缺少回归防线,重构结果只能靠运气验证 |
红灯时怎么办
- 先回退这一步,而不是就地排查:让仓库停在已知良好状态。
- 怀疑测试不稳:先确认是偶发还是确定性失败,再继续下一步。
- 一步改得太大:拆成更小的两步重跑,缩小可疑范围。
- 确认是既有缺陷:记录在案,等重构收尾后单独修,不顺手改。
什么时候先别重构
- 交付压力极高且改动会碰到关键路径:先保证可回滚,再挑低风险模块下手。
- 模块既没有测试也没有熟悉它的人:先补行为测试并小范围试改,摸清依赖。
- 目标只是「看起来更整洁」:没有明确收益的整理最容易被下一轮推翻。
- 预计改动量超过一轮评审能审完的规模:先拆成若干可独立合入的步骤。
- 模块即将被替换或下线:投入产出比低,优先保证现状稳定与可维护。
重构期间不要顺手修缺陷或加功能:出现红灯时无法分辨是结构调整还是新逻辑引入的问题。
把测试与构建时长控制在几分钟内:反馈越慢,越容易跳过测试直接提交,纪律也就无从谈起。
把每一步提交当作检查点:出现异常能退回最近一个绿灯状态,是重构最重要的安全绳。
遗留代码常缺测试:先写行为基准测试锁定当前输出,再开始改结构,比为旧代码补全测试更快见效。