4、重构原则:何时重构、何时不该重构、重构的节奏与流程
重构这件事,我见过太多团队走极端了。
要么是「代码能跑就别动」,结果项目烂成一锅粥;要么是「看哪都不顺眼,天天重构」,结果业务需求全被堵在路上。
说白了,重构不是技术活,是判断力。什么时候该动手,什么时候该忍住,这比你会多少设计模式都重要。
4.1 何时该重构:三个信号
我个人习惯,不会凭空去重构代码。一定是看到了明确的信号,才会动手。
信号一:代码开始「说谎」
什么意思?变量名叫 userList,结果里面存的是订单数据。函数叫 getUserInfo,实际还偷偷改了数据库。我在项目中遇到过这种代码,改一个 bug 要花三天,因为根本不知道哪个函数在撒谎。
代码一旦开始说谎,你就没法信任它。这时候不重构,后面每加一个功能都是在埋雷。
信号二:改一处,崩三处
你改了一个工具函数,结果五个模块报错。你加了一个字段,结果八个页面需要同步修改。这就是典型的「高耦合、低内聚」。
嗯,这里要注意:不是所有耦合都要解。但如果每次改动都像推倒多米诺骨牌,那就该重构了。
信号三:新人上手成本超过一周
团队来了个三年经验的 Node.js 工程师,看了一周代码还不敢提 PR。这不是新人菜,是代码烂。
我曾经接手过一个项目,光理清模块依赖关系就花了两周。那感觉就像在拆炸弹,每根线都不敢乱剪。后来我花了一个迭代专门做重构,把模块边界划清楚,新人三天就能上手改 bug。
4.2 何时不该重构:四个陷阱
你想想看,是不是经常有人一拍脑袋说「这段代码太丑了,重构一下」?我劝你冷静。
陷阱一:没有测试覆盖的代码
这是最大的坑。没有测试,你重构完怎么知道没改坏?靠肉眼 review?别闹了。
我曾经犯过这个错。一个老项目,没有单元测试,我自信满满重构了一个核心模块。结果上线后,三个业务方同时报错。从那以后,我定了个规矩:没有测试覆盖的代码,只修不重构。
陷阱二:临近交付截止日期
项目还有三天上线,你突然觉得路由设计不合理,想重写?千万别。
重构最大的风险是引入新 bug。在 deadline 前做重构,等于在雷区里跑步。先让项目跑起来,欠的债后面再还。
陷阱三:代码虽然丑,但稳定运行多年
有些代码看着像屎山,但它就是不出 bug。为什么?因为所有人都在小心翼翼地绕开它走。
这种代码,我建议你别碰。它丑,但它稳定。你重构完,可能引入一堆新问题。说白了,稳定压倒一切。
陷阱四:重构目标不明确
「我想让代码更优雅」——这不是重构目标,这是文艺青年的自我感动。
重构必须有明确的收益:提升性能?降低复杂度?减少重复代码?如果说不清楚重构完能带来什么具体好处,那就别动手。
4.3 重构的节奏:小步快跑
重构不是大扫除,而是日常整理。我推荐一个节奏:每次改代码时,顺手做一点重构。
| 场景 | 重构幅度 | 建议做法 |
|---|---|---|
| 修 bug 时 | 小 | 只重构 bug 所在的函数或模块 |
| 加功能时 | 中 | 重构与新增功能相关的代码区域 |
| 代码 review 时 | 小 | 发现坏味道,顺手提重构建议 |
| 专门的重构迭代 | 大 | 不超过总开发时间的 20% |
我个人习惯是「童子军规则」:每次离开营地时,让它比你刚来时更干净一点。改一个函数,顺手把变量名改清楚;加一个接口,顺手把重复的逻辑抽出来。
这样积累下来,代码会慢慢变好,而且不会影响业务进度。
4.4 重构的流程:四步走
我总结了一个简单的流程,团队里一直在用。你试试看。
- 先写测试 —— 没有测试的重构都是耍流氓。先把关键路径的测试补上,确保重构前后行为一致。
- 小步修改 —— 每次只改一个点。改完就跑测试,绿了再改下一个。别想着一次改完,那是找死。
- 频繁提交 —— 每完成一个小重构就提交一次代码。这样万一改坏了,回滚成本极低。
- 代码 review —— 重构完一定要让同事 review。自己看自己的代码,永远看不出问题。
4.5 总结一下
重构不是目的,是手段。代码整洁是为了更快地交付业务价值,不是为了满足代码洁癖。
我见过太多团队,重构上瘾,结果业务被竞争对手甩开三条街。也见过太多团队,代码烂到没人敢碰,最后只能重写。
平衡点在哪?就在你心里。记住三个原则:有测试再重构、有收益再动手、小步快跑别贪多。
嗯,做到这三点,你的重构就不会翻车。