《重构:改善既有代码的设计》—第2章2.3节何时重构

简介: 几乎任何情况下我都反对专门拨出时间进行重构。在我看来,重构本来就不是一件应该特别拨出时间做的事情,重构应该随时随地进行。你不应该为重构而重构,你之所以重构,是因为你想做别的什么事,而重构可以帮助你把那些事做好。

本节书摘来自异步社区《重构:改善既有代码的设计》一书中的第2章,第2.3节何时重构,作者【美】Martin Fowler,更多章节内容可以访问云栖社区“异步社区”公众号查看。

2.3 何时重构
当我谈论重构,常常有人问我应该怎样安排重构时间表。我们是不是应该每两个月就专门安排两个星期来进行重构呢?

几乎任何情况下我都反对专门拨出时间进行重构。在我看来,重构本来就不是一件应该特别拨出时间做的事情,重构应该随时随地进行。你不应该为重构而重构,你之所以重构,是因为你想做别的什么事,而重构可以帮助你把那些事做好。

三次法则
Don Roberts给了我一条准则:第一次做某件事时只管去做;第二次做类似的事会产生反感,但无论如何还是可以去做;第三次再做类似的事,你就应该重构。


d6f3121f2a5543d79618b29886d3f1386119b752

事不过三,三则重构。

添加功能时重构
最常见的重构时机就是我想给软件添加新特性的时候。此时,重构的直接原因往往是为了帮助我理解需要修改的代码——这些代码可能是别人写的,也可能是我自己写的。无论何时,只要我想理解代码所做的事,我就会问自己:是否能对这段代码进行重构,使我能更快地理解它。然后我就会重构。之所以这么做,部分原因是为了让我下次再看这段代码时容易理解,但最主要的原因是:如果在前进过程中把代码结构理清,我就可以从中理解更多东西。

在这里,重构的另一个原动力是:代码的设计无法帮助我轻松添加我所需要的特性。我看着设计,然后对自己说:“如果用某种方式来设计,添加特性会简单得多。”这种情况下我不会因为自己过去的错误而懊恼——我用重构来弥补它。之所以这么做,部分原因是为了让未来增加新特性时能够更轻松一些,但最主要的原因还是:我发现这是最快捷的途径。重构是一个快速流畅的过程,一旦完成重构,新特性的添加就会更快速、更流畅。 

修补错误时重构
调试过程中运用重构,多半是为了让代码更具可读性。当我看着代码并努力理解它的时候,我用重构帮助加深自己的理解。我发现以这种程序来处理代码,常常能够帮助我找出bug。你可以这么想:如果收到一份错误报告,这就是需要重构的信号,因为显然代码还不够清晰——没有清晰到让你能一眼看出bug。

复审代码时重构
很多公司都会做常规的代码复审,因为这种活动可以改善开发状况。这种活动有助于在开发团队中传播知识,也有助于让较有经验的开发者把知识传递给比较欠缺经验的人,并帮助更多人理解大型软件系统中的更多部分。代码复审对于编写清晰代码也很重要。我的代码也许对我自己来说很清晰,对他人则不然。这是无法避免的,因为要让开发者设身处地为那些不熟悉自己所做所为的人着想,实在太困难了。代码复审也让更多人有机会提出有用的建议,毕竟我在一个星期之内能够想出的好点子很有限。如果能得到别人的帮助,我的生活会滋润得多,所以我总是期待更多复审。

我发现,重构可以帮助我复审别人的代码。开始重构前我可以先阅读代码,得到一定程度的理解,并提出一些建议。一旦想到一些点子,我就会考虑是否可以通过重构立即轻松地实现它们。如果可以,我就会动手。这样做了几次以后,我可以把代码看得更清楚,提出更多恰当的建议。我不必想象代码应该是什么样,我可以“看见”它是什么样。于是我可以获得更高层次的认识。如果不进行重构,我永远无法得到这样的认识。

重构还可以帮助代码复审工作得到更具体的结果。不仅获得建议,而且其中许多建议能够立刻实现。最终你将从实践中得到比以往多得多的成就感。

为了让过程正常运转,你的复审团队必须保持精练。就我的经验,最好是一个复审者搭配一个原作者,共同处理这些代码。复审者提出修改建议,然后两人共同判断这些修改是否能够通过重构轻松实现。果真能够如此,就一起着手修改。

如果是比较大的设计复审工作,那么在一个较大团队内保留多种观点通常会更好一些。此时直接展示代码往往不是最佳办法。我喜欢运用UML示意图展现设计,并以CRC卡展示软件情节。换句话说,我会和某个团队进行设计复审,而和单个复审者进行代码复审。

极限编程[Beck,XP]中的“结对编程”形式,把代码复审的积极性发挥到了极致。一旦采用这种形式,所有正式开发任务都由两名开发者在同一台机器上进行。这样便在开发过程中形成随时进行的代码复审工作,而重构也就被包含在开发过程内了。

为什么重构有用
——Kent Beck

程序有两面价值:“今天可以为你做什么”和“明天可以为你做什么”。大多数时候,我们都只关注自己今天想要程序做什么。不论是修复错误或是添加特性,我们都是为了让程序能力更强,让它在今天更有价值。

但是系统当下的行为,只是整个故事的一部分,如果没有认清这一点,你无法长期从事编程工作。如果你为求完成今天的任务而不择手段,导致不可能在明天完成明天的任务,那么最终还是会失败。但是,你知道自己今天需要什么,却不一定知道自己明天需要什么。也许你可以猜到明天的需求,也许吧,但肯定还有些事情出乎你的意料。

对于今天的工作,我了解得很充分;对于明天的工作,我了解得不够充分。但如果我纯粹只是为今天工作,明天我将完全无法工作。

重构是一条摆脱困境的道路。如果你发现昨天的决定已经不适合今天的情况,放心改变这个决定就是,然后你就可以完成今天的工作了。明天,喔,明天回头看今天的理解也许觉得很幼稚,那时你还可以改变你的理解。

是什么让程序如此难以相与? 眼下我能想起下述四个原因,它们是:

难以阅读的程序,难以修改;
逻辑重复的程序,难以修改;
添加新行为时需要修改已有代码的程序,难以修改;
带复杂条件逻辑的程序,难以修改。
因此,我们希望程序:(1) 容易阅读;(2) 所有逻辑都只在唯一地点指定;(3) 新的改动不会危及现有行为;(4) 尽可能简单表达条件逻辑。

重构是这样一个过程:它在一个目前可运行的程序上进行,在不改变程序行为的前提下使其具备上述美好性质,使我们能够继续保持高速开发,从而增加程序的价值。

相关文章
|
设计模式
重构·改善既有代码的设计.03之重构手法(上)
之前的重构系列中,介绍了书中提到的重构基础,以及识别代码的坏味道。今天继续第三更,讲述那些重构手法(上)。看看哪些手法对你的项目能有所帮助......
19261 1
重构·改善既有代码的设计.03之重构手法(上)
|
设计模式 Java 程序员
《重构:改善既有代码的设计》-学习笔记一(+实战解析)
《重构:改善既有代码的设计》-学习笔记一(+实战解析)
206 0
《重构:改善既有代码的设计》-学习笔记一(+实战解析)
|
程序员
《重构:改善既有代码的设计》-学习笔记二(+实战解析)
《重构:改善既有代码的设计》-学习笔记二(+实战解析)
574 0
《重构:改善既有代码的设计》-学习笔记二(+实战解析)
|
消息中间件 设计模式 缓存
系统重构的道与术
准备以重构工作中容易产生误区的地方或容易被忽视的重点来聊聊,既不重复网上千篇一律的各种方案资料,也对重构工作有参考价值。
系统重构的道与术
重构-改善既有代码的设计-简化函数调用
Rename Method 函数改名 问题函数的名称未能揭示函数的用途。方法修改函数名称。动机好的函数需要有一个清晰的函数名。
1009 0
|
程序员
重构-改善既有代码的设计--重构,第一个案例
什么是重构 在不改变代码外在行为的前提下,对代码做出修改以改进程序内部的结构简单地说就是在代码写好后改进它的设计 谁该阅读这本书 专业程序员(能够提高你的代码质量) 资深设计师和架构规划师(理解为什么需要重构,哪里需要重构) 阅读技巧 带着疑问去读: 如果你想要知道重构是什么。
1104 0
|
程序员
《重构:改善既有代码的设计》—第2章2.2节为何重构
如果没有重构,程序的设计会逐渐腐败变质。当人们只为短期目的,或是在完全理解整体设计之前,就贸然修改代码,程序将逐渐失去自己的结构,程序员越来越难通过阅读源码而理解原来的设计。
1826 0