一、重构的定义与目的
1.1 到底什么是重构?
重构这个词,在圈子里被用得太滥了。很多人改了几行变量名,就说自己在重构。其实不是这样的。
我个人的理解是:重构是在不改变代码外部行为的前提下,改善内部结构的过程。说白了,就是让代码变得更好读、更好改,但功能一点不变。
你想想看,我们平时改代码,经常是改着改着就把功能改坏了。重构不一样,它有一套安全网——测试。没有测试的重构,那不叫重构,那叫「碰运气式改代码」。我在项目中遇到过太多次,有人拍着胸脯说「我就重构一下,不会出问题」,结果上线就崩。
重构的核心三要素:
- 外部行为不变(功能完全一致)
- 内部结构改善(可读性、可维护性提升)
- 有小步验证(测试保驾护航)
1.2 重构的目的:不只是为了好看
很多人觉得重构就是让代码「看起来舒服」。嗯,这只是表面。重构的真正目的,我总结为四点:
| 目的 | 说明 | 我的经验 |
|---|---|---|
| 降低修改成本 | 好结构的代码,改一处不会崩三处 | 我曾经接手过一个3000行的函数,改一个参数要排查两小时 |
| 提升可读性 | 代码是写给人看的,顺便给机器执行 | 我习惯用「5秒原则」——5秒内看不懂,就该重构了 |
| 暴露隐藏缺陷 | 重构过程中,很多隐藏的bug会自己跳出来 | 有一次重构时发现一个死循环,已经在生产环境跑了半年 |
| 为后续扩展铺路 | 好的结构让新功能像搭积木 | 我建议每次加功能前,先看看现有结构能不能撑住 |
二、重构与重写的区别
这个问题,几乎每次技术评审都会有人问。我直接说结论:重构是手术,重写是投胎。
2.1 核心区别一览
| 维度 | 重构 | 重写 |
|---|---|---|
| 风险等级 | 低(逐步改进) | 高(推倒重来) |
| 时间成本 | 可控(小步迭代) | 不可控(经常延期) |
| 业务连续性 | 不影响 | 可能长时间停摆 |
| 团队士气 | 正向积累 | 容易挫败 |
| 典型场景 | 代码混乱但逻辑清晰 | 技术栈过时、架构彻底崩塌 |
我记得有个项目,团队花了三个月重写一个模块,结果上线后bug比老系统还多。为什么?因为重写过程中,很多隐含的业务逻辑被遗漏了。重构就不一样,你每次只动一小块,测试跟着走,出了问题能立刻定位。
避坑指南:我曾经见过一个团队,把「重构」当幌子,实际上在重写。结果项目延期半年,老板直接叫停。记住:如果你需要停掉现有系统才能「重构」,那其实是在重写。
2.2 什么时候必须重写?
也不是所有情况都适合重构。我总结了几种必须重写的场景:
- 技术栈已经停止维护(比如Flash项目)
- 代码完全没有测试,且逻辑混乱到无法理解
- 架构设计存在根本性缺陷(比如单点瓶颈)
- 团队没有人理解现有代码(文档也丢了)
但说实话,我工作十几年,真正需要重写的项目不超过三个。大多数情况,重构都能解决问题。
三、重构的时机判断
这是最实际的问题。什么时候该动手?什么时候该忍住?我分享两个我常用的法则。
3.1 童子军规则
这个规则很简单:离开时,让营地比你来时更干净。放到代码里就是:每次你修改一个文件,顺手把它变得比之前好一点点。
不需要大动干戈。比如:
- 看到一个变量名起得不好,顺手改掉
- 发现一个函数太长,抽出一个子函数
- 看到重复代码,提取成公共方法
我个人的习惯是:每次提交代码前,花5分钟看看有没有可以顺手改进的地方。别小看这5分钟,一年下来,代码质量会有质的提升。
小技巧:童子军规则的关键是「顺手」。不要为了重构而重构,而是在日常修改中顺便改善。我曾经有个同事,每次改bug都要重构整个模块,结果bug没修好,反而引入新问题。
3.2 三次法则
这个法则更具体。简单说就是:第一次做,直接写;第二次遇到类似的,先忍住;第三次再出现,立刻重构。
为什么会这样?因为前两次你还不确定这是不是通用模式。第三次出现,基本可以确认这是一个稳定的需求了。
举个例子:
// 第一次:直接写
function calculateTax(amount) {
return amount * 0.13;
}
// 第二次:又来了类似的
function calculateServiceFee(amount) {
return amount * 0.05;
}
// 第三次:该重构了
const feeCalculators = {
tax: (amount) => amount * 0.13,
service: (amount) => amount * 0.05,
// 以后扩展直接加
};
我建议团队把这个法则写进代码评审规范里。看到第三次重复还不重构,那就该打回去重写了。
3.3 其他判断信号
除了上面两个法则,还有一些信号提醒你该重构了:
- 测试越来越慢:说明耦合度太高
- 改一个bug引出三个新bug:代码的脆弱性在报警
- 新功能加不进去:结构已经僵化
- 代码评审没人愿意看:太复杂了,看不懂
我的经验:如果你在代码评审时,花了10分钟还没看懂一个函数在干什么,那就该重构了。别犹豫,越拖越难改。
知识体系总览
下面这张图,把本章的核心内容串起来了。你可以把它当作一个快速参考:
这张图把三个核心知识点串在了一起。你可以看到,定义与目的是「为什么做」,重构与重写是「做什么选择」,时机判断是「什么时候做」。三者缺一不可。
最后说一句:重构不是一次性的活动,而是一种习惯。我见过最好的团队,不是他们代码写得有多好,而是他们每天都在让代码变得更好一点。童子军规则也好,三次法则也罢,核心都是「持续改进」这四个字。