重构还是重写,先看这三个条件

我那个后台服务是三年前写的,今年上半年我动过一次重写的念头,方案写到第二版就自己否了。原因很具体:服务里沉淀了三年的边界处理——空值怎么算、超时怎么退、历史脏数据怎么兼容,这些逻辑没有任何文档记录,只活在代码里。真要重写,等于把这些坑全部重踩一遍。重构还是重写怎么选,我的判断落在三个条件上。

先给结论:只有「旧代码的边界逻辑可以重新推导」时,重写才是选项;推导不出来,就老老实实重构。

一、四个维度上的真实差别

| 维度 | 重构 | 重写 |

|---|---|---|

| 上线节奏 | 分多次小步上,每次都能回退 | 一次性切换,切完才知道行不行 |

| 隐藏逻辑 | 原地保留,不容易丢 | 需要重新发现一遍,漏了就是线上事故 |

| 时间确定性 | 结束点难预估,但每天有产出 | 前期看不到产出,后期容易超期 |

| 老代码价值 | 历史修复全部继承 | 历史修复要重新赚一遍 |

| 适合的模块 | 缺陷集中在结构上 | 需求本身已经变了,旧结构没保留价值 |

这张表里我最看重第二行。重写最大的成本不是写新代码,是重新发现旧代码里那些没写下来的规则。

二、什么情况下重构更划算

判断标准就一条:旧代码的行为是对的,只是组织方式不好。

行为对意味着它踩过的坑都已经踩过、修过了。这些修复以各种不起眼的分支散落在代码里,看着丑,其实是资产。这时候重构是「把资产换个柜子放」。

反过来,如果旧代码的行为本身就不对——业务规则变了、数据结构撑不住了,那保留它就没什么意义。

三、重写真正成立的三个条件

第一个条件:旧代码的行为能被完整说清楚。 要么有测试覆盖,要么你能讲出每个分支在防什么。讲不出来就别重写。

第二个条件:这次重写有明确的功能范围,并且允许先只替换一部分。 全量一次性切换的风险太高,能灰度就灰度。

第三个条件:重写的收益能量化。 不是「代码更好看」,而是「这个模块的改动频率很高,现在改一次要花很久」。改动频率低的模块,重写完也看不出好处。

三个条件缺任意一个,我都会退回重构。少一个条件就上,等于用一个确定的投入换一个不确定的收益。

四、我最后的选择

我选的是重构,而且只重构改动最频繁的那几个入口。

有一个信号帮我做了决定:翻提交记录,发现近期的改动集中在少数几个文件上,其他文件几个月没动过。没动过的代码,重写它就是纯粹的浪费。

真要动刀之前,我会先解决测试的问题,因为没测试的重构和重写一样危险。这一点在代码没测试怎么改安全,我试过三条路里写得更细。

常见问题

Q:重构和重写该怎么选,有没有一句话的判断?

A:旧代码行为正确、只是结构差,就重构;旧代码行为本身已经不适用、且你能完整讲清它的规则,才考虑重写。

Q:重写一定会超期吗?

A:不确定会不会超期,但重写的前期没有可交付物,进度很难从外部判断。想控风险,就把重写范围缩到一个模块,而不是整个服务。

Q:老项目没有任何测试,还能重构吗?

A:能,但要先给要改的部分补上能跑通主流程的测试。没有这层保护,重构和重写没有区别。

相关阅读


本文作者西米,37 岁程序员,一个人加五个 AI 员工在跑一家公司。踩过的坑和真实账本都写在公众号「西米分享」。

完整代码、踩坑清单与最新进展,都在公众号。

📱 关注公众号「西米分享」