洪流学堂,让你快人几步。
本篇内容来自洪流读书会精选内容。
上次我们从区分重构与性能优化、重构时我们的角色定位两个方面对重构的原则进行了解读,今天我将从重构带给我们什么、何时重构两个方面来为大家进一步解读重构的原则。
重构的原则
重构带给我们什么
重构能带给我们什么?
重构可以改进软件的设计,使软件更容易理解,帮助找到bug,提高编程速度。
如果没有重构,程序的架构会逐渐腐败变质。当人们只为短期目的而修改代码时,他们经常没有完全理解架构的整体设计,于是代码逐渐失去了自己的结构。程序员越来越难通过阅读源码来理解原来的设计。
如果对代码进行重构,就可以深入理解代码的所作所为,并立即把新的理解反映在代码当中。搞清楚程序结构的同时,也验证着自己所做的一些假设,这样下来想不把bug揪出来都难,也因此重构能够帮助我们更有效地写出健壮的代码,何乐而不为呢?
何时重构
什么时候开始重构才是最佳时机呢?
接下来我将介绍一个简易的三次法则用来判断是否需要重构:
第一次要做某件事或者要实现某些功能你只管去做;
第二次做类似的事可能会产生反感,但无论怎样还是可以勉强去做;
第三次再做类似的事,你就应该重构。
简而言之:事不过三、三则重构。
何时开始重构?我将重构的开始时机分为六种情形:
第一种是预备性重构:
重构的最佳时机就在添加新功能之前,先看看现有的代码库中如果进行一次微调是否能让工作变得容易。比如我要往东去100公里,我不会往东一头把车开进树林,而是先往北开20公里上高速,然后再向东开100公里。后者的速度比前者要快上3倍。如果有人催着你“赶紧直接去那儿”,有时你需要说:“等等,我要先看看地图,找出最快的路径。”
这就是预备性重构的意义。
第二种是帮助理解的重构:
重构带来的帮助常常是立竿见影的。我会先在一些小细节上使用重构来帮助理解,给一两个变量改名,让它们更清楚地表达意图,以方便理解,或是将一个长函数拆分成几个小函数。当代码变得更清晰一些时,我就会看见之前看不见的设计问题。在研读代码时,重构会引领我获得更高层面的理解,如果只是阅读代码很难由此领悟。有些人以为重构只是毫无意义的把玩代码,他们没有意识到,缺少了细微的整理,他们就无法看到隐藏在一片混乱背后的机遇。
第三种是捡垃圾式重构:
这种类型适用于:我已经理解代码在做什么,但发现它做得不好。
例如设定的逻辑不必要地迂回复杂,或者两个函数几乎完全相同,可以用一个参数化的函数取而代之。这里有一个取舍:我不想从眼下正要完成的任务上跑题太多,但我也不想把垃圾留在原地,给将来的修改增加麻烦。如果我发现的垃圾很容易重构,我会马上重构它;如果重构需要花一些精力,我可能会先记录下来,待完成当下的任务后再重构它。
第四种是有计划地重构和见机行事的重构:
这种类型的重构不用专门安排一段时间进行,而是在添加新功能或修复bug的同时顺便重构。
重构本身不是与编程割裂的行为,你不会安排专门时间重构,正如你不会专门安排时间写if语句。我的项目计划上没有专门留给重构的时间,绝大多数重构都在我做其他事的过程中自然发生。
优秀的程序员都知道,添加新功能最快的方法往往是先修改现有的代码,使新功能更容易被加入。所以,软件永远不应该被视为“完成”。每当需要新功能时,软件就应该做出相应的改变。
第五种是长期型重构:
有一些大型的重构可能要花上几星期,例如要替换一个正在使用的库,或者将整块代码抽取到一个组件中并共享给另一支团队使用该怎么办?再或者要处理一大堆混乱的依赖关系时该怎么办?
我们可以让整个团队先达成共识,在未来几周的时间内逐步解决这个问题。每当有人靠近“重构区”的代码,就把它朝想要改进的方向推动一点。这个策略的好处在于,重构不会破坏代码,每次小改动后整个系统仍然照常工作。例如,如果想替换掉一个正在使用的库,可以先引入一层新的抽象,使其兼容新旧两个库的接口。一旦调用方法已经完全改为使用这层抽象,替换下面的库就会容易得多。
第六种是复审代码时重构:
代码复审有助于在开发团队中传播知识,集思广益的同时也将代码更清晰化。
开始复审前可以先阅读代码,得到一定程度的理解,并提出一些建议。一旦想到一些点子,就可以通过重构立即轻松的实现它们,趁热打铁好过回炉重塑啊!
小结
今天我们从重构带给我们什么、何时重构两个方面为大家进一步解读了重构的原则。下次我将带大家了解应该选择在何处重构。
扩展阅读
【扩展学习】在洪流学堂回复
读书会
可以阅读本系列所有文章,还有更多精选内容等着你!
我是大智,你的技术探路者,下次见!
别走!点赞,收藏哦!
好,你可以走了。
网友评论