- 前言
近期在看Martin Fowler著作的《重构.改善既有代码的设计》这本书,这是一本经典著作。书本封面誉为软件开发的不朽经典。书中从一个简单的案例揭示了重构的过程以及最佳实践。同时给出了重构原则,何时重构,以及重构的手法。用来改善既有代码的设计,提升软件的可维护性。
这里会对本书持续进行阶段性总结,希望自己能够从中学习到精髓。
- 什么是重构
书中提到,所谓重构(refactoring)是这样一个过程:在不改变代码外在行为的前提下,对代码做出修改,以改进程序的内部结构。
通常一个系统的第一个版本会经过很大很精细的设计,且会遵循先设计后编码的开发流程。但是随着时间的流逝,人们会不断的修改代码。中间随着人员的流动,项目业务性质的变化......,如果按照原先设计所得系统,整体结构会逐渐衰弱,或者说渐渐偏离起初的设计。这样,编码工作就会从一开始的严谨逐渐堕落为胡砍乱劈的随性。
书中提到重构的2层含义:
名词,对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可理解性,降低其修改成本。 动词,使用一系列重构手法,在不改变软件可观察行为的前提下,调整其结构。
- 两顶帽子
当我们在重构软件时,经常会把时间分配给两种截然不同的行为:
- 添加新功能
- 重构
添加新功能时,你不应该修改既有的代码,只管添加新功能。编写测试,你可以衡量自己的工作进度。
重构时,你就不能再添加新功能,只管改进程序结构,此时不应该添加任何的测试,只在绝对必要时才修改测试。
但是往往我们在开发过程中,会发现要经常变换帽子。首先你会尝试添加新功能,然后意识到:如果把程序结构改一下,功能添加会容易很多。于是乎,你就换了一定帽子,做一会重构工作。等程序结构调整好后,你又换上原先的帽子继续添加新功能......但无论何时,你都应该清楚知道自己戴的是哪顶帽子。
- 为何重构
- 重构改进软件设计
当人们只为短期目的,或是在完全理解整体设计之前,就贸然修改代码,程序会逐渐失去自己的结构,程序员越来越难通过阅读源码而理解原来的设计。重构很像是在整理代码,你所做的就是让后所有的东西回到应处的位置上。
代码结构的流失是累积性的,越难看出代码所代表的设计意图,就越难保护其中的设计,于是该设计就腐败的越快。经常性的重构可以帮助代码维持自己该有的形态。
因此改进设计的一个重要方向就是:消除重复代码。
- 重构使软件更容易理解
一般情况下,我们所编写的代码告诉计算机要做什么事,他的响应则是精确按照你的指示行动。但是除了计算机外,你的源码还有其他读者:几个月后可能会有另一位程序员尝试读懂你的代码并尝试做一些修改。
通常,当你努力的让程序正常运转的时候,很容易忘记第二位读者,但是未来出现的读者(开发者)才是最重要的。计算机多花了几个小时编译,又有什么关系呢?如果一个程序员花一周的时间修改代码,这才要命。有可能理解了你的代码之后,真正的修改只需一个小时。
所以我们应该改变一下开发节奏,对代码适当进行修改,让代码变得更容易理解。这种编程模式的核心就是“准确说出我所要的”。
- 重构帮助找到bug
对代码进行重构,可以深入理解代码的作为,并恰到好处的把新的理解反馈回去。搞清楚程序结构的同时,也清楚了自己所作的一些假设,于是想不把bug揪出来都很难。
- 重构提高编程速度
良好的设计是快速开发的根本,事实上,拥有良好的设计才可以做到快速开发。
如果没有好的设计,或者在起初阶段,你的进展会很迅速。但是缺乏设计(或恶劣的设计)很快会让你的速度慢下来。你会把时间花在调试上,无法添加新功能。修改时间越来越长,因为你必须花越来越多的时间去理解系统、寻找重复代码。各种打补丁,新特性需要更多的代码才能实现,一直恶性循环下去。
所以前面的一些都归结到这一点:重构帮助你更快速的开发程序。
- 何时重构
- 三次法则
书中提到了Don Roberts提出的准则:
- 第一次做某件事,只管去做;
- 第二次做类似的事情会产生反感,但无论如何还是可以去做;
- 第三次做类似的事,你就应该重构。
事不过三,三则重构
- 添加功能时重构
这里,重构的一个原动力是:代码的设计无法帮助我轻松和那个添加所需要的特性。然后对自己说:“如果用某种方式设计,添加特性会简单很多。”这么做的部分原因是为了让未来增加新特性时能够更轻松一些。
- 修补错误时重构
调试过程中运用重构,多半是为了让代码更具可读性。如果收到一份错误报告,这就是需要重构的信号,因为显然代码还不够清晰,至少没有清晰到让你能一眼看出bug。
- 复审代码时重构
极限编程[XP]中的“结对编程”形式,把代码复审的积极性发挥到了极致。一旦采用这种形式,所有正式开发任务都由2名开发者在同一台机器上进行,这样便在开发过程中形成随时进行的代码复审工作,而重构也被包含在开发过程中了。
- 何时不该重构
1、代码根本无法工作,或太糟糕。代码重构还不如重写来的简单; 2、在项目的最后期限,应该避免重构。
小结
到此,刚看完整本书的2个章节。重构和设计模式等诸多思想一样,是需要反复学习,反复实践的。重构的技术就是以微小的步伐修改程序。希望真正吸收这些之后,能够看到一个不一样的代码世界。借此,共勉~
1、如果发现自己需要为程序添加一个特性,而代码结构使得你无法很方便地达成目的,那么就需要重构那个程序了。使特性的添加比较容易进行,然后再添加特性。 2、代码块越小,代码的功能就越容易管理,代码的处理和移动也就越轻松。 3、代码应该表现自己的目的。任何一个人都能写出计算机可以理解的代码,唯有写出人类容易理解的代码,才是优秀程序员。
后续阶段性阅读该书后,会持续更新中......