🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
### 何时重构 当我谈论重构,常常有人问我应该怎样安排重构时间表。我们是不是应该每两个月 就专门安排两个星期来进行重构呢? 几乎任何情况下我都反对专门拨出时问进行重构。在我看来,重构本来就不是一件「特别拨出时间做」的事情,重构应该随时随地进行。你不应该为重构而重构,你之所以重构,是因为你想做别的什么事,而重构可以帮助你把那些事做好。 **三次法则〔The Rule of Three〕** Don Roberts给了我一条准则:第一次做某件事时只管去做;第二次做类似的事会产生反感,但无论如何还是做了;第三次再做类似的事,你就应该重构。 Tip: 事不过三,三则重构(Three strikes and you refactor) **添加功能时一并重构** 最常见的重构时机就是我想给软件添加新特性的时候。此时,重构的第一个原因往往是为了帮助我理解需要修改的代码。这些代码可能是别人写的,也可能是我自己写的。无论何时只要我想理解代码所做的事,我就会问自己:是否能对这段代码进行重构,使我能更快理解它。然后我就会重构。之所以这么做,部分原因是为了让我下次再看这段代码时容易理解,但最主耍的原因是:如果在前进过程中把代码结构理清,我就可以从中理解更多东西。 在这里,重构的另一个原动力是:代码的设计无法帮助我轻松添加我所需要的特性。我看着设计,然后对自己说:「如果用某种方式来设计,添加特性会简单得多」。这种情况下我不会因为自己过去的错误而懊恼——我用重构来弥补它。之所以这么做,部分原因是为了让未来增加新特性时能够更轻松一些,但最主要的原因还是:我发现这是最快捷的途径。重构是一个快速流畅的过程,一旦完成重构,新特性的添加就会更快速、更流畅。 **修补错误吋一并重构** 调试过程中运用重构,多半是为了让代码更具可读性。当我看着代码并努力理解它的时候,我用重构帮助改善自己的理解。我发现以这种程序来处理代码,常常能够帮助我找出臭虫。你可以这么想:如果收到一份错误报告,这就是需要重构的信号,因为显然代码还不够清晰一不够清晰到让你一目了然发现臭虫。 **复审代码吋一并重构** 很多公司都会做常态性的代码复审工作(code reviews),因为这种活动可以改善开发状况。这种活动有助于在幵发团队中传播知识,也有助于让较有经验的开发者把知识传递给比较欠缺经验的人,并帮助更多人理解大型软件系统中的更多部分。代码复审工作对于编写清晰代码也很重要。我的代码也许对我自己来说很清晰,对他人则不然。这是无法避免的,因为要让幵发者设身处地为那些不熟悉自己所做所为的人设想,实在太困难了。代码复审也让更多人有机会提出有用的建议,毕竟我在一个星期之内能够想出的好点子很有限。如果能得到别人的帮助,我的生活会舒服得多,所以我总是期待更多复审。 我发现,重构可以帮助我复审别人的代码。开始重构前我可以先阅读代码,得到一定程度的理解,并提出一些建议。一旦想到一些点子,我就会考虑是否可以通过重构立即轻松地实现它们。如果可以,我就会动手。这样做了几次以后,我可以把代码看得更清楚,提出更多恰当的建议。我不必想像代码「应该是什么样」,我可以「看见」它是什么样。于是我可以获得更髙层次的认识。如果不进行重构,我永远无法得到这样的认识。 重构还可以帮助代码复审工作得到更具体的结果。不仅获得建议,而且其中许多建议能够立刻实现。最终你将从实践中得到比以往多得多的成就感。 为了让过程正常运转,你的复审团队必须保持精练。就我的经验,最好是一个复审者搭配一个原作者,共同处理这些代码。复审者提出修改建议,然后两人共同判断这些修改是否能够通过重构轻松实现。果真能够如此,就一起着手修改。 如果是比较大的设计复审工作,那么,在一个较大团队内保留多种观点通常会更好一些。此时直接展示代码往往不是最佳办法。我喜欢运用示意图展现设计,并以CRC卡展示软件情节。换句话说,我会和某个团队进行设计复审,而和个别 (单一〉复审者进行代码复审。 极限编程(Extreme Programming)[Beck, XP]中的「搭档(成对〉编程」(Pair Programming)形式,把代码复审的积极性发挥到了极致。一旦采用这种形式,所有正式开发任务都由两名开发者在同一台机器上进行。这样便在开发过程中形成随时进行的代码复审工作,而重构也就被包含在幵发过程内了。 **为什么重构有用(Why Refactoring Works)** —— Kent Beck 程序有两面价值:「今天可以为你做什么」和「明天可以为你做什么」。大多数时候,我们都只关注自己今天想要程序做什么。不论是修复错误或是添加特性,我们都是为了让程序力更强,让它在今天更有价值。 但是系统当下行为,只是整个故事的一部分,如果没有认清这一点,你无法长期从事编程工作。如果你「为求完成今天任务」而釆取的手法使你不可能在明天完成明天的任务,那么你还是失败。但是,你知道自己今天需要什么,却不一定知道自己明天需要什么。也许你可以猜到明天的需求,也许吧,但肯定还有些事情出乎你的意料。 对于今天的工作,我了解得很充分:对于明天的工作,我了解得不够充分。但如果我纯粹只是为今天工作,明天我将完全无法工作。 重构是一条摆脱束缚的道路。如果你发现昨天的决定已经不适合今天的情况,放心改变这个决定就是,然后你就可以完成今天的工作了。明天,喔,明天回头看今天的理解也许决定幼稚,那是你还可以改变你的理解。 是什么让程序如此难以相与?下笔此刻,我想起四个原因,它们是: - 难以阅读的程序,难以修改。 - 逻辑复杂(duplicated logic)的程序,难以修改。 - 添加新行为时需要修改既有代码者,难以修改。 - 带复杂条件逻辑(complex conditional logic)的程序,难以修改。 因此,我们希望程序:(1)容易理解;(2)所有逻辑都只在唯一地点指定;(3)新的改动不会危及现有行为;(4)尽可能简单表达条件逻辑(conditional logic)。 重构是这样一个过程:它在一个目前可运行的程序上进行,企图在「不改变程序行为」的情况下赋予上述美好性质,使我们能够继续保持高速开发,从而增加程序的价值。