编程核心能力之重构
今天推荐第二本经典《重构》,目前出了第二版。
看到这本书的内容,就让我想起了「鲁班学艺」的故事,我稍微改编了下:
老师傅把鲁班领到西屋。原来西屋里摆了好多模型,有「函数」有「变量」有「参数」有「类」,有「记录」有「集合」有「字段」有「语句」,各式各样,精致极了,鲁班把眼睛都看花了。老师傅笑着说:“你把这些模型「重构」出来再「反重构」回去,每个模型都要「重构」一遍,「反重构」一遍,自己专心学,手艺就学好了。”
老师傅说完就走出去了。鲁班拿起这一件,看看那一件,一件也舍不得放下。他把模型一遍遍抄下来,重构和反重构反复地抄,每一件都认真「重构」三遍「反重构」三遍。
鲁班苦学了三年,把所有的「重构」都学会了。老师傅还要试试他,把遗留代码回退,让他现场重构。他凭记忆,一件一件都重构得跟模型一模一样。老师傅又给了好多遗留代码让他重构。他一边琢磨一边重构,结果都按师傅说的式样做出来了。老师傅非常满意。
《重构》就是那个老师傅,你愿意做鲁班吗?
「重构能力」
这引出了编程必不可少的另一项能力:重构。
上面提到「鲁班学艺」这个故事,是想说明,重构虽然大部分内容讲的是如何做,即 HOW 的层面。但其目的并非止于此。
我们通过长期的重构练习和实践,是为了获得一种能力,暂且把这种能力就叫做「重构」。
先来看看拥有了这种能力后的情景:发现一个坏味道,然后重构掉这个坏味道,提交代码。然后继续发现坏味道,或者已经没有坏味道。
可以从中整理出下面三个子能力:
发现不好的代码,也就是坏味道,即重构的对象
知道什么是好的代码,即重构后的结果
以及如何从不好到好的步骤,即重构过程
当然,理想的情况是一次性写出没有坏味道的代码。
但在达到这个水平之前,重构的练习必不可少,可以说重构就是达到这个水平的途径。
「封面故事」
如果说书中的内容是讲如何把代码重构做正确,那封面的图片则是在强调如何正确地去重构。
备注一下,以下的信息是在重构的译者熊节老师的群里获得的。
图片中有两座桥,是并排的,左边那座明显在技术是落后于右边那座,意味着技术上已经有了迭代更新。
而且左边那座已经破败不堪,只是在勉强维持,右边的则是新的,可见,右边这座桥建设的原因就是因为左边的桥使用寿命快结束了。
分析到这里,重构能力三要素中的2个已经出现,左边的桥就是坏味道,右边的桥就是重构后的结果。
这些都比较明显,但重构的过程在这张图中有体现吗?
关键的来了,想象一下右边的新桥在建设的过程中是什么情形,左边的桥肯定还在投入使用,直到右边的桥完全建成,左边的桥才能退役。这也是两座桥并排建的原因,桥的迭代重构并没有影响业务的运行。
另一个常见的隐喻就是:给飞行中的飞机换引擎。
ThoughtWorks 有人编了重构口诀:
「旧的不变,新的创建,一键切换,旧的再见。」
如果记不住口诀,就想想封面上这张图。
《重构》这本书这么厚,有接近1000页,该「如何读」?
有这个疑问的,肯定是觉得这么多内容,看了大概率也都会忘记。
在具体展开之前,先说下我对看书的态度:
大家应该听过这样一句话「把书读厚,然后再把书读薄」,所以,不管厚书,还是薄书,都有其好处:厚书天然把事情讲得很细,省了你自己花力气读厚,你要做的就是将其读薄;薄书则刚好相反,其内容精炼,需要自己去费力读厚,读薄时就容易许多。
重构就是这么一本厚书,其中内容有很多冗余的地方,但却是不可多得的练习材料。
另外,编程是一门输出活动,必须脑子里先有所需的全部概念,才能输出,缺少一点都会卡住;
解决方法就是加强输入:输入不好的做法,可以加强对坏味道的识别能力;输入好的做法,如最佳实践,则能形成思维模式,提高输出效率;最终习得重构能力。
什么是代码的「坏味道」?
坏味道是指代码中的某些特定结构。
《重构》一书中有专门一章来介绍,给出了 24 个,对应 24 个结构或场景。
里面涉及了几乎全部的编程要素:函数,参数,变量,字段,语句,对象,类,循环等。
今天我们从另外个角度分析下,是关于选择的取舍:
倾向于清晰的命名,而不是随意的
倾向于复用,而不是重复
倾向于短小的代码,而不是过长、过大
倾向于不可变的,隐藏修改,而不是开放修改
倾向于变化单一,而不是发散
倾向于抽象数据,而不是原始的繁琐
倾向于管道操作,而不是循环
倾向于恰到好处的表达,而不是过度抽象
「重构动作」
《重构》一书共讲了 61 个重构方法,我们提取其中的动词,试着按照开发过程串联一下,来感受下其中的味道。
我们最喜欢的应该是「提炼」,这意味着将有新的结构诞生;
如果提炼受阻,则要先进行「分解」「分离」「拆分」使代码达到方便提炼的程度;
提炼完了,一般会做一些调整,如「搬移」「取代」「改变」「替换」「上移」「下移」,使代码在新的结构下表现的更自然;
调整完后,再看一下有没有重构过度的,适当进行「内联」「合并」「隐藏」「折叠」;
如果发现多余的代码,则直接「移除」;
最后,从整体上考虑「组合」和「封装」。
「重构的阻力」
或者说,重构执行不力的原因有哪些?
首先一点是,在软件项目管理或公司管理的过程中,很多人强调“只看结果”,轻视做事的过程与方式,长期下来,导致对软件开发“正确的做事方式”缺乏重视。
另外一点是,“先做对,再做好”这个软件开发方式,在前半部分完成后,就没人再理会后半部分了。
这种方式本身的出发点是好的,可以尽早实现软件的价值,但如果忽略后半部分,就成了只关注短期价值,而忽略长期价值。
我们不能以此为借口,对自己降低要求,当然不是只管对,不管好,而是尽自己所能去做好。尤其是,明知自己有一些不好的习惯时,如果每次都为了「对」而迁就「不好」时,则自己的坏习惯也没机会得到改善。
正如《重构》在推荐语中,庄表伟所说:了解本书中列出的那些坏味道,不仅仅可以发现代码中的那些坏味道,更可以鞭策自己以及整个团队:在一开始的时候,就不写或者少些那种味道很坏的代码。
因为学习《重构》,是为了减少“重构”!
版权声明: 本文为 InfoQ 作者【顿晓】的原创文章。
原文链接:【http://xie.infoq.cn/article/5b2380d3d72ab83a01564ea24】。文章转载请联系作者。
评论