分享

艰难的重构:10大常见的重构误区

 昵称32348297 2016-04-13


相信大家平时在工作中必定免不了被遗留代码折磨,想要下决心重构吧,总有各种各样的理由让重构难以推行,最后还是拿着旧代码凑合用。重构是编程的一次变革,它从根本上改变了某些旧有的习惯,因此必然会面对许多阻力,让不知所以者感到无比的困惑。下面列出的常见重构误区,你遇见过吗?

1
“如果没有坏,就不要修复它”

这句话老少相传,可谓工程智慧的真实写照,但是这种想法只会滋生得过且过的情绪。


在你编程生涯的早期,一定明白“千里之堤,溃于蚁穴”的道理,并为之而付出过沉重代价。即使一个细微的变化,都会导致软件在最糟糕的时刻以莫名其妙的方式停止运转。一朝被蛇咬,十年怕井绳,故而你害怕任何变化的发生,只要变化不是必须的。然而这只能够苟延残喘维持一时。一旦形势急转直下,出现的错误不得不解决,新的功能需求也不能一拖再拖了。此时你面对的代码即使是相同的,但实际却已养成了大患。


许多经验丰富的程序员之所以认可这种观点,是因为对一些不必要工作“偷工减料”,乃人之常情,是合情合理的。譬如说,如果应用程序已经具备优越的性能,就无需为了性能对处理器周期耗费心机。类似的投机性设计,通常会用来搪塞那些具有前瞻性的编程观点,诸如“我们可能会在将来的某一天需要这一特性”。


从这个意义上讲,重构需要随时进行。在重构时,你需要消除冗余代码,避免投机性设计或预先优化。


而对于重构的老手来讲,这样的软件完全是“金玉其外,败絮其中”。如果设计有瑕疵,例如拙劣的代码和糟糕的结构,那么在软件外部是看不到这些问题的。然而即使应用程序在某个时候能够正常运行,我们仍然需要对此进行重构,对设计进行优化。从这个意义上讲,重构坚持在一些不太明显,但却具有决定性作用的特征上作文章,例如设计、简单性,以及改善源代码的可读性,便于理解。


重构可以帮助你赢回对代码的支配权。这对于那些业已脱离控制的代码库而言并非易事,如果不诉诸于重构,那么唯一的解决之道就是彻底地重写。

2
重构是高科技

编程是一项复杂活动,需要大量的知识积累。某些知识可能很难掌握,而其好处则在于学习一门新的技能绝对是物有所值的。


重构的伟大之处就在于它的简单。只需了解很小的一套简单规则,再加上一个好的工具,迈开重构的第一步简直就是轻而易举。与一个高级程序员应该了解的其他技术相比,重构有着最简单的学习曲线。


学习重构很快就会迎来你的收获季节。当然,与世间万事万物相同,知识的学习总是“一份耕耘,一份收获”的。

3
重构会导致性能低下

复杂点儿的说法是“因为重构通常会引入大量的细粒度元素(如方法和类),这种间接的设计会导致性能的损失。”


让我们把时钟往回调一小段,你会发现这样的观点似曾相识,当初在质疑面向对象编程时,就发出过类似奇怪的声音。


事实的真相是代码结构重构与否,在性能上的区别微乎其微,所以常常可以忽略不计,除非是某些特别的系统。


经验证明,性能总是受制于某一段确定的代码。在优化阶段修复它们,可以获得你需要的性能等级。能够轻易地识别关键代码是重中之重。减少代码的重复与数量,从而使得代码易于理解,一旦发生变化,也只会影响到单独的模块,这样的重构极大地改善了优化的过程。

4
重构会破坏好的面向对象设计

具有优美结构以及经过重构的代码,在菜鸟的眼里是笨拙而粗陋的。方法是如此的短小,在他们看来简直言之无物。类显得不够重量级,仅仅包含屈指可数的几个成员。这样的代码看起来简直就等于没有嘛。


像类和方法那样,若要管理大量的元素,则意味着需要处理的复杂度会加大。


这样的观点常会引人误解。事实上,复杂度总是相同的。但重构后的代码会显得条理更清晰,结构更合理。

5
重构无法提供短期利益

一个占据主流的论调是重构可以使得你的程序更快。迄今为止并没有相关的研究可以证明我的看法,但我的经验告诉我存在这样的情形,这是唯一合乎逻辑的——由于你在整体上具有少量的代码,极少的重复以及清晰的意图,因此重构带来的益处很快就能彰显无遗,除非你处理的是一些可有可无、也无任何实际意义的小规模代码。

6
重构只适宜敏捷团队

在敏捷方法学中,重构是被频繁提及的关键技术之一,因而通常的解释是,重构只有在遵循敏捷原则的团队中才能如鱼得水。


其实不然,即使你的团队采取别的开发方式,但如果是由你来负责管理编码方式,这时就是运用重构的时机。没人能阻止你在IDE中使用“Refactor”选项。如果你遵循小步重构,并在编码过程中定期执行,就能达到最佳的重构效果。某些实践例如严格的代码所有权或瀑布过程,可能会与重构背道而驰。如果你能够证明重构从编程的视角来看是有意义的,你就可以开始构建你的支撑库,首先从你的伙伴开始,然后推广到整个团队。

7
重构可以作为独立阶段实施,由独立团队执行

经理们通常对此深以为然。将重构视为一个独立的阶段,然后将其放在诸如实现阶段和测试阶段期间,从管理学的角度来看,容易给人一种错觉,认为重构就是甘特图的一根线条,可以轻易地将其压缩时间甚至移走。


事实上,为了成功地执行重构,你需要完整地理解整个问题域,了解需求、设计甚至实现阶段的细节。倘若你从一开始就没有将实施重构的人看作团队的一份子,也没有花时间与客户交流,分析需求和思考设计,你将很难改善最初的团队构建的内容。


遵循某种模型,则代码可以通过它在编码之后得到精化,就像工业生产过程中提炼出的某种物质那样,总会带来一些好处。若是不能切实地理解代码的意义,则你真正能够对重构保有信心的只能是一些细微的改进。若在此种情形下,妄图通过重构使代码焕然一新,结果很有可能是南辕北辙,适得其反。代码若与问题域紧密相关,就有可能使得事情变得更加糟糕,最终还会为你的应用程序引入bug。

8
没有单元测试重构照样能工作

我想,一些简单的重构可以在没有单元测试的情形下进行。重构工具与编译器自身可以提供一定的安全保障,不至于引入一些简单的人为错误。你也可以采用传统方式对代码进行测试,例如使用调试器或者执行功能测试。但这些手动的测试方法却是乏味而不值得信赖的。重构时,代码比以前对修改更为敏感与脆弱。若要避免不必要的问题,则应添加单元测试放到项目中。在你执行每一小步重构时,就能够及时发现错误。

9
不要依赖注释的观点未必正确

毫无疑问,你已经千百次地被告知,在编写代码时一定要添加注释。作为一种好的编程实践,这种思想会帮助别人理解你的代码。这通常意味着编码的方式是优秀的、有序的、专业的。因此,如果现在有人居然胆敢告诉你注释未必是一桩好事儿,你一定会大吃一惊。


添加注释的动机通常与代码重构一致。你应该竭力提高代码的可读性。在早期,编程工具受制于标识符的长度,故而注释成为了传达编程涵义的唯一选择。立足于重构,则要求代码是自解释性的,即选择正确的方法、类、变量以及其他标识符。同时,你应该避免为了相同的目的使用注释,因为注释不会被执行,且很容易作废。在每日的编程成为急就章时,总是会忘记更新注释、文档、图示或其他次等级的工件。

10
拼音缩写命名法怎么了?

“拼音缩写命名也可以嘛,多熟悉几天这个部分你就都看得懂了”。


使用那些类似人类的自然语言为变量命名,可以使得代码简明易懂。拜托放弃那些拼音首字母,转而使用别人能够轻松理解的词语吧。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多