一、重构初探:什么是重构?为什么要重构?重构与性能优化的区别
各位同学好,我是这门课的主讲人。今天咱们聊聊重构这件事。
说实话,我写了快二十年代码,见过太多烂代码。我自己也写过不少。嗯,谁还没年轻过呢?但真正让我下定决心系统研究重构的,是十年前一个项目——那个项目让我连续加了三个月班,就为了改一个本来两周就该搞定的功能。
从那以后,我养成了一个习惯:每次提交代码前,先问问自己——这段代码,三个月后的我看得懂吗?
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 为什么要重构?
这个问题我问过很多开发者。最常见的回答是:「代码太烂了,看不下去了。」
嗯,这确实是个理由。但不够。
我个人认为,重构的真正价值在于三点:
- 降低修改成本——好代码改起来快,烂代码改起来想哭
- 减少缺陷率——结构清晰的代码,bug 无处藏身
- 提升团队效率——新人上手快,老人不憋屈
我曾经在一个项目里接手过一段 3000 行的函数。对,你没看错,一个函数 3000 行。我花了整整一周才搞清楚它到底在干什么。后来我花了三周把它拆成 30 个小函数。结果呢?原来一个 bug 要修两天,现在两小时搞定。
我的经验:重构不是浪费时间,而是在投资。你今天花一小时重构,可能为未来省下十小时。这笔账,怎么算都划算。
还有一个容易被忽视的原因:重构能帮你理解代码。很多时候,你以为你理解了代码,但当你开始重构时,才发现「咦,这里为什么这么写?」「这个分支逻辑好像有问题?」重构的过程,其实就是深度阅读代码的过程。
1.3 重构与性能优化的区别
这个问题经常有人搞混。我面试时也喜欢问这个。
简单来说:
- 重构关注的是「人」——代码的可读性、可维护性
- 性能优化关注的是「机器」——代码的执行速度、内存占用
两者有时会冲突。你想想看,为了让代码跑得更快,你可能需要写一些「丑陋」的技巧——比如位运算代替除法、缓存计算结果、手动展开循环。这些优化往往会让代码更难懂。
反过来,重构有时也会降低性能。比如把一个大的函数拆成多个小函数,会增加函数调用的开销。但这种开销通常微乎其微,不值得担心。
| 维度 | 重构 | 性能优化 |
|---|---|---|
| 目标 | 改善代码结构 | 提升运行效率 |
| 关注点 | 可读性、可维护性 | 速度、内存、IO |
| 外部行为 | 不变 | 不变 |
| 风险 | 低(小步进行) | 中高(可能引入bug) |
| 何时做 | 持续进行 | 有明确性能需求时 |
重要提醒:千万不要在重构的同时做性能优化。一次只做一件事。如果你既想重构又想优化,请先重构,再优化。或者反过来,但别混在一起。否则你根本搞不清问题是出在重构还是优化上。
我记得有个同事,重构和优化一起搞。结果代码改完后,功能坏了,性能也没提升。他花了三天才找到问题——原来是一个重构步骤不小心改错了逻辑。如果分开做,这个问题五分钟就能定位。
1.4 什么时候不该重构?
说了这么多重构的好处,也得说说什么时候不该重构。
- 代码马上就要被重写——别费劲了,直接重写吧
- 代码马上就要被废弃——别浪费时间了
- 没有足够的测试覆盖——没有安全网,重构就是走钢丝
最后一点特别重要。我见过太多人,没有测试就敢重构。结果呢?改完发现功能不对,又改回来。来回折腾,浪费时间。
所以我的建议是:重构之前,先写测试。哪怕只是几个核心用例的测试,也比没有强。
1.5 本章知识体系
下面这张图总结了本章的核心内容,你可以把它当作一个思维导图来看:
这张图展示了本章的三个核心模块。你可以看到,重构的核心是「人」,而性能优化的核心是「机器」。两者目标不同,方法也不同,但都是软件开发中不可或缺的技能。
好了,第一章就到这里。记住一句话:重构不是锦上添花,而是雪中送炭。它不是什么高深的技术,而是一种习惯,一种态度。从今天开始,试着在每次修改代码时,顺手做一点小重构。三个月后,你会感谢自己的。