一、通过 3 个问题了解重构
1.我业务都开发不完,哪有时间重构呀?
这是我接触重构首先想到的问题,也是我一直没有学习它的原因。但从数据来看,程序员50%的时间是在写代码,而这中间绝大部分时间是在读代码,可以说写代码就是读代码。
图表1:开发人员时间分布(图片来自《奔跑吧,程序员》)
“重构的意义不在于把代码库打磨得闪闪发光,而是纯粹从经济角度出发的考量。重构唯一目的就是让我们开发更快,用更少的工作量创造更大的价值。”
随着项目体量增加,代码阅读难度会越来越高,开发的速度也会越来越缓慢。而重构可以让代码更好读,它不会耽误业务开发,反而可以加速业务开发。
图表2:好的设计与坏的设计(图片来自《重构:改善既有代码的设计》)
2.重构出问题来怎么办?
人总会有出错的时候,不过只要及时发现,就不会造成大问题。这里的关键就在于“快速发现错误”。要做到这一点,我的代码应该有一套完备的测试套件,并且运行速度要快,否则我会不愿意频繁运行它。也就是说,绝大多数情况下,如果想要重构,我得先有可以自测试的代码。
以前提起自测,头一下就大了,但现在是 AI 时代!代码自测试变得比以往更加简单高效。各种智能测试工具可以帮助我们快速生成测试用例、发现潜在问题,甚至自动修复代码,大大降低了测试的门槛和成本。
3.现在的项目体量太大,重构的成本太高了。
重构≠把项目完全重写。保证你离开时的代码库比来时更健康这就是重构!
二、重构的原则
何谓重构
“重构”这个词既可以用作名词也可以用作动词。
- 重构(名词):对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可理解性,降低其修改成本。
- 重构(动词):使用一系列重构手法,在不改变软件可观察行为的前提下,调整其结构。
为何重构
- 重构改进软件的设计。如果没有重构,程序的内部设计(或者叫架构)会逐渐腐败变质。
- 重构使软件更容易理解。重构可以帮我让代码更易读。
- 重构帮助找到 bug。如果对代码进行重构,我就可以深入理解代码的所作所为,并立即把新的理解反映在代码当中。
- 重构提高编程速度。前面的一切都归结到了这一点:重构帮我更快速地开发程序。
何时重构
- 何时重构?第一次做某件事时只管去做;第二次做类似的事会产生反感,但无论如何还是可以去做;第三次再做类似的事,你就应该重构。
- 如何和经理说我要重构?不要告诉他。受进度驱动的经理要我尽可能快速完成任务,至于怎么完成,那就是我的事了。我领这份工资,是因为我擅长快速实现新功能;我认为最快的方式就是重构,所以我就重构。
- 何时不应该重构?如果代码凌乱但又无须修改时或者重写比重构还简单时就不必重构了。
重构的挑战
- 延缓新功能开发。“重构会拖慢进度”这种看法仍然很普遍,这可能是导致人们没有充分重构的最大阻力所在。我们之所以重构,因为它能让我们更快——添加功能更快,修复 bug 更快。一定要随时记住这一点,与别人交流时也要不断强调这一点。重构应该总是由经济利益驱动。程序员、经理和客户越理解这一点,“好的设计”那条曲线就会越经常出现。
- 测试。不会改变程序可观察的行为,这是重构的一个重要特征。重构前一定要有测试用例。
三、接下来内容安排
接下来用四篇文章介绍重构的具体方法,他们分别是:
一、闻味,识别代码中的“坏味道”
二、测试,避免引入问题
三、重构,改善既有代码的设计
四、JavaScript 特有的重构手法