一、重构初探:什么是重构?为什么要重构?重构与性能优化的区别

各位同学好,我是这门课的主讲人。今天咱们聊聊重构这件事。

说实话,我写了快二十年代码,见过太多烂代码。我自己也写过不少。嗯,谁还没年轻过呢?但真正让我下定决心系统研究重构的,是十年前一个项目——那个项目让我连续加了三个月班,就为了改一个本来两周就该搞定的功能。

从那以后,我养成了一个习惯:每次提交代码前,先问问自己——这段代码,三个月后的我看得懂吗?

1.1 什么是重构?

先给个定义。重构,说白了就是:在不改变代码外部行为的前提下,改善其内部结构

注意两个关键词:

  • 不改变外部行为——功能不能变,测试不能红
  • 改善内部结构——让代码更容易理解、更容易修改

我见过很多团队把「重构」和「重写」混为一谈。你想想看,重写是推倒重来,重构是一步步微调。两者天差地别。

核心要点:重构是一系列小步骤的累积。每一步都很小,小到你觉得「就这?这也算重构?」但正是这些小步骤,最终让代码脱胎换骨。

举个例子。假设你看到这样一段代码:

function calculate(price, type, quantity) {
  let result = 0;
  if (type === 'normal') {
    result = price * quantity;
  } else if (type === 'vip') {
    result = price * quantity * 0.8;
  } else if (type === 'super_vip') {
    result = price * quantity * 0.6;
  }
  return result;
}

这段代码能跑,但问题不少。if-else 堆砌、魔法数字、职责不清晰。重构的第一步,可能只是把魔法数字提取成常量:

const VIP_DISCOUNT = 0.8;
const SUPER_VIP_DISCOUNT = 0.6;

function calculate(price, type, quantity) {
  let result = 0;
  if (type === 'normal') {
    result = price * quantity;
  } else if (type === 'vip') {
    result = price * quantity * VIP_DISCOUNT;
  } else if (type === 'super_vip') {
    result = price * quantity * SUPER_VIP_DISCOUNT;
  }
  return result;
}

你看,功能没变,测试照样跑过。但代码的可读性已经提升了。这就是重构——每一步都很小,但方向正确。

1.2 为什么要重构?

这个问题我问过很多开发者。最常见的回答是:「代码太烂了,看不下去了。」

嗯,这确实是个理由。但不够。

我个人认为,重构的真正价值在于三点:

  1. 降低修改成本——好代码改起来快,烂代码改起来想哭
  2. 减少缺陷率——结构清晰的代码,bug 无处藏身
  3. 提升团队效率——新人上手快,老人不憋屈

我曾经在一个项目里接手过一段 3000 行的函数。对,你没看错,一个函数 3000 行。我花了整整一周才搞清楚它到底在干什么。后来我花了三周把它拆成 30 个小函数。结果呢?原来一个 bug 要修两天,现在两小时搞定。

我的经验:重构不是浪费时间,而是在投资。你今天花一小时重构,可能为未来省下十小时。这笔账,怎么算都划算。

还有一个容易被忽视的原因:重构能帮你理解代码。很多时候,你以为你理解了代码,但当你开始重构时,才发现「咦,这里为什么这么写?」「这个分支逻辑好像有问题?」重构的过程,其实就是深度阅读代码的过程。

1.3 重构与性能优化的区别

这个问题经常有人搞混。我面试时也喜欢问这个。

简单来说:

  • 重构关注的是「人」——代码的可读性、可维护性
  • 性能优化关注的是「机器」——代码的执行速度、内存占用

两者有时会冲突。你想想看,为了让代码跑得更快,你可能需要写一些「丑陋」的技巧——比如位运算代替除法、缓存计算结果、手动展开循环。这些优化往往会让代码更难懂。

反过来,重构有时也会降低性能。比如把一个大的函数拆成多个小函数,会增加函数调用的开销。但这种开销通常微乎其微,不值得担心。

维度 重构 性能优化
目标 改善代码结构 提升运行效率
关注点 可读性、可维护性 速度、内存、IO
外部行为 不变 不变
风险 低(小步进行) 中高(可能引入bug)
何时做 持续进行 有明确性能需求时

重要提醒:千万不要在重构的同时做性能优化。一次只做一件事。如果你既想重构又想优化,请先重构,再优化。或者反过来,但别混在一起。否则你根本搞不清问题是出在重构还是优化上。

我记得有个同事,重构和优化一起搞。结果代码改完后,功能坏了,性能也没提升。他花了三天才找到问题——原来是一个重构步骤不小心改错了逻辑。如果分开做,这个问题五分钟就能定位。

1.4 什么时候不该重构?

说了这么多重构的好处,也得说说什么时候不该重构。

  • 代码马上就要被重写——别费劲了,直接重写吧
  • 代码马上就要被废弃——别浪费时间了
  • 没有足够的测试覆盖——没有安全网,重构就是走钢丝

最后一点特别重要。我见过太多人,没有测试就敢重构。结果呢?改完发现功能不对,又改回来。来回折腾,浪费时间。

所以我的建议是:重构之前,先写测试。哪怕只是几个核心用例的测试,也比没有强。

1.5 本章知识体系

下面这张图总结了本章的核心内容,你可以把它当作一个思维导图来看:

重构初探 什么是重构? 不改变外部行为 改善内部结构 小步骤累积 为什么要重构? 降低修改成本 减少缺陷率 提升团队效率 与性能优化的区别

这张图展示了本章的三个核心模块。你可以看到,重构的核心是「人」,而性能优化的核心是「机器」。两者目标不同,方法也不同,但都是软件开发中不可或缺的技能。


好了,第一章就到这里。记住一句话:重构不是锦上添花,而是雪中送炭。它不是什么高深的技术,而是一种习惯,一种态度。从今天开始,试着在每次修改代码时,顺手做一点小重构。三个月后,你会感谢自己的。