代码重构不是重写,是给老代码做一次“理疗”

上周帮朋友改一个跑着的电商小系统,他指着一段300多行的订单处理函数说:“这代码我都不敢动,怕一改就崩。”——其实这不是代码太老,而是它太久没“理疗”了。

重构不是推倒重来

很多人一听“重构”,第一反应是:重写!删掉旧代码,从头来过。错。重构(Refactoring)的核心动作只有一个:不改变外部行为的前提下,优化内部结构。就像修水管,水照样流、水压不变,只是把锈蚀的弯头换成更顺滑的直管,把缠成团的胶带换成卡扣式接口。

它不新增功能,也不修复 bug(那是调试的事),就是让代码更容易看懂、更容易改、更容易加新东西。

什么时候该动手?

别等项目上线前夜才想起重构。这几个信号一出现,就该安排了:

  • 每次改个字段名,得查5个地方,改完还不确定有没有漏;
  • 新加一个优惠规则,得在 if-else 里嵌套三层再加个 else if;
  • 同事问你“这段 for 循环里为啥要先 reverse 再 filter”,你愣三秒才想起来是为了兼容老数据格式;
  • 单元测试一跑就报17个红,但业务居然还在跑……

一个小而实在的重构例子

原始代码(PHP 风格):

$discount = 0;
if ($userType === 'vip') {
if ($orderAmount > 500) {
$discount = 0.15;
} else {
$discount = 0.08;
}
} elseif ($userType === 'partner') {
if ($orderAmount > 1000) {
$discount = 0.2;
} else {
$discount = 0.1;
}
} else {
$discount = 0;
}

问题在哪?逻辑散、重复判断、难加新用户类型、折扣值藏在数字里没人看得懂。

重构后(提取策略 + 命名清晰):

function calculateDiscount($userType, $orderAmount) {
$strategies = [
'vip' => new VipDiscountStrategy(),
'partner' => new PartnerDiscountStrategy(),
];
return $strategies[$userType] ?? new DefaultDiscountStrategy()
->apply($orderAmount);
}

不用改业务调用,只换了个实现方式——可读性、可扩展性、可测试性全上了一个台阶。

别碰这三类“雷区”

重构不是越勤快越好,避开这些坑才真省事:

  • 没测试覆盖的模块:别急着动。先补几个核心路径的单元测试(哪怕只有3个),确保你改完之后“结果没变”能被验证;
  • 正在紧急上线的功能分支:这时候重构=给自己加戏。等版本发完,安静两天再动手;
  • 别人写的、文档为零、又没人能问的“祖传脚本”:先花1小时把它跑通、记下输入输出样例,再动第一行。

重构不是炫技,是让明天的自己和同事少骂一句“谁写的这玩意儿”。它不靠大刀阔斧,靠的是每天改一小段、命名更准一点、函数职责更单一一点、注释少写一句“这里很奇怪但别动”——时间久了,代码就活过来了。