为什么重构
KISS 原则,Keep It Simple and Stupid。
重构不是包治百病的灵丹妙药,也绝对不是所谓的“银弹”。不过它的确很有价值,尽管它不是一颗“银弹”,却可以算是一把“银钳子”,可以帮你始终良好地控制自己的代码。重构是一个工具,它可以(并且应该)用于以下几个目的。
改进软件的设计
如果没有重构,程序的内部设计(或者叫架构)会逐渐腐败变质。当人们只为短期目的而修改代码时,他们经常没有完全理解架构的整体设计。于是代码逐渐失去了自己的结构。程序员越来越难以通过阅读代码来理解原来的设计。代码结构的流失有累积效应。越难看出代码所代表的设计企图,就越难以保护其设计,于是设计就腐败得越快。经常性的重构有助于代码维持自己该有的形态。
完成同样一件事,设计欠佳的程序往往需要更多代码,这常常是因为代码在不同的地方使用完全相同的语句做同样的事情,因此改进设计的一个重要方向就是消除重复代码。消除重复代码,我就可以确定所有事物和行为在代码中只表述一次,这正是优秀设计的根本。
使软件更容易理解
所谓程序设计,很大程度上就是与计算机对话:我编写代码告诉计算机做什么事,而它的响应是按照我的指示精确行动。一言以蔽之,我所做的就是填补“我想要它做什么”和“我告诉它做什么”之间的缝隙。编程的核心就在于“准确说出我想要的”。然而别忘了,除了计算机外,源码还有其他读者:几个月之后可能会有另一位程序员尝试读懂我的代码并对其做一些修改。我们很容易忘记这这位读者,但他才是最重要的。计算机是否多花了几个时钟周期来编译,又有什么关系呢?如果一个程序员花费一周时间来修改某段代码,那才要命呢——如果他理解了我的代码,这个修改原本只需一小时。
问题在于,当我努力让程序运转的时候,我不会想到未来出现的那个开发者。是的,我们应该改变一下开发节奏,让代码变得更易于理解。重构可以帮我让代码更易读。开始进行重构前,代码可以正常运行,但结构不够理想。在重构上花一点点时间,就可以让代码更好地表达自己的意图——更清晰地说出我想要做的。
关于这一点,我没必要表现得多么无私。很多时候那个未来的开发者就是我自己。此时重构就显得尤其重要了。
帮助找到 BUG
对代码的理解,可以帮我找到bug。我承认我不太擅长找bug。有些人只要盯着一大段代码就可以找出里面的bug,我不行。但我发现,如果对代码进行重构,我就可以深入理解代码的所作所为,并立即把新的理解反映在代码当中。搞清楚程序结构的同时,我也验证了自己所做的一些假设,于是想不把bug揪出来都难。
这让我想起了Kent Beck经常形容自己的一句话:“我不是一个特别好的程序员,我只是一个有着一些特别好的习惯的还不错的程序员。”重构能够帮助我更有效地写出健壮的代码。
提高编程速度
听起来可能有些反直觉,因为重构可能会花大量的时间改善设计、提高阅读性、修改 BUG,难道不是在降低开发速度嘛?
软件开发者交谈时的故事:一开始他们进展很快,但如今想要添加一个新功能需要的时间就要长得多。他们需要花越来越多的时间去考虑如何把新功能塞进现有的代码库,不断蹦出来的bug修复起来也越来越慢。代码库看起来就像补丁摞补丁,需要细致的考古工作才能弄明白整个系统是如何工作的。这份负担不断拖慢新增功能的速度,到最后程序员恨不得从头开始重写整个系统。
但有些团队的境遇则截然不同。他们添加新功能的速度越来越快,因为他们能利用已有的功能,基于已有的功能快速构建新功能。
两种团队的区别就在于软件的内部质量。需要添加新功能时,内部质量良好的软件让我可以很容易找到在哪里修改、如何修改。良好的模块划分使我只需要理解代码库的一小部分,就可以做出修改。如果代码很清晰,我引入 BUG 的可能性就会变小,即使引入了 BUG,调试也会容易得多。理想情况下,代码库会逐步演化成一个平台,在其上可以很容易地构造与其领域相关的新功能。
这种现象被作者称为“设计耐久性假说”:通过投入精力改善内部设计,我们增加了软件的耐久性,从而可以更长时间地保持开发的快速。目前还无法科学地证明这个理论,所以说它是一个“假说”。
20年前,行业的陈规认为:良好的设计必须在开始编程之前完成,因为一旦开始编写代码,设计就只会逐渐腐败。重构改变了这个图景。现在我们可以改善已有代码的设计,因此我们可以先做一个设计,然后不断改善它,哪怕程序本身的功能也在不断发生着变化。由于预先做出良好的设计非常困难,想要既体面又快速地开发功能,重构必不可少。
《没有银弹:软件工程的本质性与附属性工作》-
在民俗传说里,所有能让我们充满梦靥的怪物之中,没有比狼人更可怕的了,因为它们会突然地从一般人变身为恐怖的怪兽,因此人们尝试着查找能够奇迹似地将狼人一枪毙命的银弹。
我们熟悉的软件项目也有类似的特质(以一个不懂技术的管理者角度来看),平常看似单纯而率直,但很可能一转眼就变成一只时程延误、预算超支、产品充满瑕疵的怪兽,所以,我们听到了绝望的呼唤,渴望有一种银弹,能够有效降低软件开发的成本,就跟电脑硬件成本能快速下降一样。
from 《重构-改善既有代码的设计》