重构的本质是改善内部结构而不改变外部行为。跨文件重构风险高于单文件修改,因为调用点、类型契约、测试与配置都可能需要同步。本节给出前置条件、安全步骤、一致性清单和行为保持判据。
一、动手前的两个前置条件
- 验证基线可用:先确认现有测试、构建与类型检查能够跑通;若关键行为无测试,先补最小特征测试或记录可复现的行为样例,作为重构前后对照。
- 范围边界清晰:明确本次只做结构调整,不夹带需求变更;功能修改与重构分开推进,避免"改结构+改行为"混在一起无法审查。
二、安全重构六步
- 梳理依赖:依据上一节的模块地图,列出被改模块的定义处、调用方、类型/接口引用与相关测试。
- 小步抽取或移动:一次只做一种结构调整(如提取公共逻辑、调整归属文件、统一参数传递),不叠加多种改动。
- 每步验证:完成一小步即运行对应测试与构建,保持全程绿。
- 审查改动范围:通过只读版本控制命令核对实际修改文件与差异,确认没有夹带无关变更。
- 同步关联位置:更新调用点、导入关系、类型定义、测试与必要文档。
- 整体回归:全部步骤完成后跑完整测试与构建,抽查关键输入输出与边界行为。
三、跨文件一致性清单(容易漏改的位置)
| 类别 | 需要同步检查的位置 |
| 代码引用 | 所有调用点、导入语句、导出索引、类型与接口声明 |
| 测试 | 受影响用例、测试夹具、断言与辅助函数 |
| 配置与脚本 | 构建/运行脚本、环境配置、路径引用 |
| 文档与注释 | 说明文档、README、注释中描述的结构与用法 |
| 外部契约 | 对外接口字段、持久化键、URL、消息格式——这类通常不可随意重构 |
四、行为保持的判据
- 测试全部通过,且关键输入的输出结果与重构前一致。
- 正常路径、错误路径与边界条件的对外行为(报错提示、返回结构、副作用时机)保持一致。
- 不改变性能关键路径的明显开销,除非本次目标就包含性能优化并单独说明。
- 若重构后行为发生变化,应明确这是需求调整而非重构,并单独评审。
五、风险分级与回退
- 低风险:纯内部命名、局部提取、格式整理,可在测试护航下较快推进。
- 高风险:核心算法、共享数据结构、对外契约相关代码,先补测试、拆更小步、逐步验证。
- 可回退:按节奏整理提交,使每一步都能独立回退;发现偏差时先撤销未验证的大改动,再从绿色基线重新开始。
不要把重构和新需求混在一轮
同一轮同时改结构、改行为、加功能,会让 diff 难以审查、测试难以定位失败原因。应先完成并验证行为不变的重构,再另起任务实现新需求。
六、小步提交节奏,保证每步可回退
- 每完成一种结构调整(如一次提取、一次移动、一次命名统一)并通过对应测试,就整理成一个独立提交。
- 提交信息说明"纯结构调整、行为不变",便于审查者聚焦差异而非猜测行为变化。
- 任一步测试转红,先回退到上一个绿色提交定位问题,不在红色基线上继续叠加重构。
- 全部结构调整完成后,再做一次整体回归与关键行为抽查,确认行为保持判据成立。
七、重构 FAQ
| 问题 | 处理建议 |
| 没有测试,如何保证重构不改变行为 | 先补最小特征测试或记录关键输入输出样例作为对照;高风险共享代码缺少安全网时不做大范围移动,只做低风险局部整理。 |
| 重构中发现原实现有隐藏 Bug | 先记录并单独建缺陷任务,不在重构提交里顺手修复;否则无法区分"结构调整"与"行为变化"。 |
| 跨多个服务/包的结构调整如何推进 | 先稳定对外契约,再由内向外逐层调整;每改一层跑该层测试,跨服务变更用独立工作副本隔离并人工核对接口兼容。 |
| 重命名后出现遗漏引用 | 以全量构建/类型检查与测试作为兜底信号;同时按第三节清单核对导入、导出索引、配置与文档中的引用。 |
| 代理一次性给出大范围重构 diff | 要求拆成单一目的的小步序列并给出每步验证命令;先执行第一步,确认绿色后再继续,避免一次性不可审查的大改动。 |
八、动手练习
- 练习 1:选一段重复逻辑做提取,全程保持测试绿色,把提取过程拆成至少两个聚焦提交,并向审查者说明"行为未变"的证据来源。
- 练习 2:对照第三节一致性清单,检查一次既有重构是否漏改了测试、配置或文档引用,列出遗漏项并补齐。
本节小结与下一节预告
本节掌握了安全重构步骤、小步提交节奏、跨文件一致性清单、FAQ 与行为保持判据。下一节讲命名、常量与用户可见文案的批量统一:如何定位全部出现点、区分可改与不可改的契约,并验证替换无遗漏、无误伤。