《重构》语录
Amassed by Allen Lee
0.0 ...一开始只需概略浏览名录,看看其中有些什么,不必理解所有细节。一旦真正需要实施某个准则,再详细阅读它,让它来帮助你。名录是一种具备查询价值的章节,你也许并不想一次把它全部读完。...
1.0 ...一开始介绍某个东西时,首先应该大致讲讲它的历史、主要原理等等。可是每当有人在会场上介绍这些东西,总是诱发我的瞌睡虫。我的思绪开始游荡,我的眼神开始迷离,直到他或她拿出实例,我才能够提起精神。实例之所以可以拯救我与太虚之中,因为它让我看见事情的真正行进。谈原理,很容易流于泛泛,又很难说明如何实际应用。给出一个实例,却可以帮助我把事情认识清楚。
1.1 即便如此,这个程序还是能正常工作。所以这只是美学意义上的判断,只是对丑陋代码的厌恶,是吗?在我们修改这个系统之前的确如此。编译器才不会在乎代码好不好看呢。但是当我们打算修改系统的时候,就涉及到了人,而人在乎这些。差劲的系统是很难修改的,因为很难找到修改点。如果很难找到修改点,程序员就很有可能犯错,从而引入“臭虫”(bugs)。
1.2 你的态度也许倾向于“尽量少修改程序”:不管怎么说,它还运行得很好。你心里头牢牢记着那句古老的工程学格言:“如果他没坏,就别动它”。这个程序也许还没坏掉,但它带来了伤害。它让你的生活比较难过,因为你发现很难完成客户所需的修改。这时候就该重构技术粉墨登场了。
1.3 如果你发现自己需要为程序添加一个特性,而代码结构是你无法很方便地那么做,那就先重构那个程序,使特性的添加比较容易进行,然后再添加特性。
1.4 更改变量名称是值得的行为吗?绝对值得。好的代码应该清楚表达出自己的功能,变量名称是代码清晰的关键。如果为了提高代码的清晰度,需要修改某些东西的名字,大胆去做吧。
1.5 任何一个傻瓜都能写出计算机可以理解的代码。惟有写出人类容易理解的代码,才是优秀的程序员。
2.0 从许多角度来说,所谓程序设计,便是与计算机交谈。你编写代码告诉计算机做什么事,它的响应则是精确按照你的指示行动。你得及时填补“想要它做什么”和“告诉它做什么”之间的缝隙。这种编程模式的核心就是“准确说出吾人所欲”。除了计算机外,你的源代码还有其他读者:数个月之后可能会有另一位程序员尝试读懂你的代码并做一些修改。我们很容易忘记这位第二位读者,但他才是最重要的。计算机是否多花了数个钟头进行编译,又有什么关系呢?如果一个程序员花费一周时间来修改某段代码,那才关系重大——如果他理解你的代码,这个修改原本只需一小时。
2.1 ...很多时候那个“未来的开发者”就是我自己。此时重构就显得尤其重要了。我是个很懒惰的程序员,我的懒惰表现形式之一就是:总是记不住自己写过的代码。事实上对于任何立可查阅的东西我都故意不去记它,因为我怕把自己的脑袋塞爆。我总是尽量把该记住的东西写进程序里头,这样我就不必记住它了。
2.2 一开始我所作的重构都像这样停留在细枝末节上。随着代码渐趋简洁,我发现自己可以看到一些以前看不到的设计层面的东西。如果不对代码做这些修改,也许我永远看不见它们,因为我的聪明才智不足以在脑子里把这一切都想象出来。Ralph Johnson把这种“早期重构”描述为“擦掉窗户上的污垢,使你看得更远”。
2.3 我不是一个伟大的程序员;我只是个有着一些优秀习惯的好程序员而已。
2.4 ...重构本来就不是一件“特别拨出时间做”的事情,重构应该随时随地进行。你不应该为重构而重构,你之所以重构,是因为你想做别的什么事,而重构可以帮助你把那些事做好。
2.5 第一次作某件实事只管去做;第二次作类似的事会产生反感,但无论如何还是做了;第三次在做类似的事,你就应该重构。
2.6 ...系统今天(当下)的行为,只是整个故事的一部分,如果没有认清这一点,你无法长期从事编程工作。如果你“为求完成今天任务”而采取的首发式你不可能在明天完成明天的任务,那么你还是失败。但是,你知道自己今天需要什么,却不一定知道自己明天需要什么。也许你可以猜到明天的需求,也许吧,但肯定还有些事情出乎你的意料。
2.7 我们希望程序:(1)容易阅读;(2)所有逻辑都只在为一地点指定;(3)新的改动不会危及现有行为;(4)尽可能简单表达条件逻辑。
2.8 当然,很多经理嘴巴上说自己“质量驱动”,其实更多是“进度驱动”。这种情况下我会给他们一个较有争议的建议:不要告诉经理!
2.9 受进度驱动的经理要我尽可能快速完事,至于怎么完成,那就是我的事了。我认为最快的方式就是重构,所以我就重构。
2.10 我们知道重构的好处,我们知道重构可以给我们的工作带来垂手可得的改变。但是我们还没有获得足够的经验,我们还看不到它的局限性。
2.11 不要过早发布接口。请修改你的代码拥有权政策,是重构更顺畅。
2.12 重写(而非重构)的一个清楚讯号就是:现有代码根本不能正常运行。
2.13 将“大块头软件”重构为“封装良好的小型组件”。
2.14 如果项目已近最后期限,你也应该避免重构。在此时机,从重构过程赢得的生产力只有在最后期限过后才能体现出来,而那个时候已经是不我予。Ward Cunningham对此有一个很好的看法。他把未完成的重构工作形容为“债务”。很多公司都需要借债来势自己更有效的运转。但是借债就得付利息,过于复杂的代码所造成的“维护和扩展的额外开销”就是利息。你可以承受一定程度的利息,但如果利息太高你就会被压垮。把债务管理好是很重要的,你应该随时通过重构来偿还一部分债务。
2.15 哪怕你完全了解系统,也请实际量测它的性能,不要臆测。臆测会让你学到一些东西,但十有八九你是错的。
2.16 我发现重构可以帮助我写出更快的软件。短程看来,重构的确会使软件变慢,但它是优化阶段中的软件性能调整更容易。最终我还是有赚头。
4.0 当测试数量达到一定程度之后,测试效益就会呈现递减态势,而非持续递增;如果试图编写太多测试,你也可能因为工作量太大而气馁,最后什么都写不成。你应该把测试集中在可能出错的地方。观察代码,看哪儿变得复杂;观察函数,思考哪些地方可能出错。
5.0 该在何时发表自己的想法?发表愈早,人们愈快能够运用新想法、新观念。但只要是人,总是不断在学习。如果过早发表半生不熟的想法,这些思想可能并不完善,甚至可能给那些尝试采用它们的人带来麻烦。