《重构 改善既有代码的设计》(第二章)【重构的原则】

何谓重构

  • 名词定义:对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可礼节性,降低其修改成本
  • 动词定义:使用一系列重构手法,在不改变软件可观察行为的前提下,调整期结构

重构的关键在于运用大量微小且保持软件行为的步骤,一步步达成大规模的修改。每个单独的重构要么很小,要么由若干小步骤组合而成。因此,在重构过程中,不应该出现代码不可工作的状态。换句话说,如果代码在重构过程中有一两天的时间不可用,基本上可以确定,他们在做的不是重构

重构与性能优化

相似处
  • 都需要修改代码,并且两者不会改变程序的整体功能
不同处
  • 重构是为了让代码"更容易理解,更易于修改"。可能是程序运行得更快,也有可能更慢
  • 性能优化则只关心让程序运行得更快,最终得到的代码可能更难理解和维护

使用重构技术开发软件时,可以把时间分配给两个行为:添加新功能和重构。添加新功能时,不应该修改既有代码,只管添加新功能。通过添加测试并让测试正常运行,可以衡量自己的工作进度。重构时就不能再添加功能,只管调整代码的结构。此时不应该添加任何测试,只在绝对必要时才修改测试。

为何重构

重构改进软件的设计

如果没有重构,程序的内部设计(或叫做架构)会逐渐腐败变质。经常性的重构有助于代码维持自己该有的形态。

改进设计的一个重要方向就是消除重复代码,代码量减少将使未来可能的程序修改动作容易得多。

重构使软件更容易理解

重构帮助找到bug

重构能够帮助更有效地写出健壮的代码。

重构提高编程速度

系统开发中往往存在两种局面:一种是刚开始开发进展很快,之后需要添加新功能时不考虑重构,导致开发时间长得多。接下来塞到现有代码中的时间越来越长,不断蹦出新的bug修复也不容易修改。最终不断地累加后,程序员受不了产生重写整个系统的想法;另一种则是在添加新功能时,利用已有的功能,基于已有的功能快速构建新功能,速度自然是很快的。

上面介绍的其实就是两种团队,区别就在于软件的内部质量。因此通过投入精力改善内部设计,增加了软件的耐久性,从而可以更长时间地保持开发的快速,这也是作者提出的"设计耐久性假说"

何时重构

预备性重构:让添加新功能更容易

重构的最佳时机就在添加新功能之前。

帮助理解的重构:使代码更易懂

在开始修改代码前,一般都要先理解代码是在做什么。通过重构,可以把理解转移到代码本身。随后运行这个软件,看是否正常工作,来检查这些理解是否正确。在研读代码时,重构会获得更高层面的理解,如果只是阅读代码很难有此领悟。

捡垃圾式重构

有计划的重构和见机行事的重构

实际重构是不需要专门安排一段时间来处理的。一般在添加功能或修复bug的同时顺便重构。这里也有一个误区,“肮脏的代码必须重构,但漂亮的代码不需要重构”,后半句是不对的,要衡量实际的情况,判断是否需要对已经整洁的代码进行重构。

优秀的程序员知道,添加新功能最快的方法往往是先修改现有的代码,使功能容易被加入。而将重构与添加新功能在版本控制的提交中分开作者认为是没有必要的,重构常常与新添加功能是紧紧交织的,不值得花时间把它们分开。只要记住:分离重构提交并不是毋庸置疑的原则,只有当你真的感到有益时,才值得这样做

长期重构

对于很多重构可能需要很长的时间,甚至要几个星期。对于这种类型的重构,可以让整个团队达成共识,在未来几周时间里逐步解决这个问题。如果有人靠近了"重构区"额代码,就把它朝想要的方向进行改进推动。好处在于重构不会破坏代码–每次小改动之后,整个系统仍然照常工作。对于正在使用的库,可以先引入一层新的抽象,使其兼容新旧两个库的接口。一旦调用方法已经完全改为使用这层抽象,再替换掉原来的库。

复审代码时重构

一些公司会做常规的代码复审(code review),因为这种活动可以改善开发状况。代码复审有助于在开发团队中传播知识,也有助于让较有经验的开发者把知识传递给比较欠缺经验的人,并帮助更多人理解大型软件系统中的更多部分。

如何在代码复审的过程中加入重构,要取决于复审的形式。一种方式为常见的pull request模式下,复审者独自浏览代码,代码的作者不在旁边,此时进行重构效果并不会好;另一种则是,代码的原作者在旁边,原作者提供关于代码的上下文信息,并且充分认同复审者进行修改的意图。第二种方式很自然地导向结对编程:在编程过程中持续不断地进行代码复审

何时不应该重构

只有当需要理解其工作原理时,才去做重构,才会有价值。如果该代码隐藏在一个API之下,那这个情况下在不了解原理的情况下,尽量别重构。

而对于重构和重做,需要衡量重构花的时间和重做时间到底哪个更长些。决定到底应该重构还是重写,需要良好的判断力与丰富的经验。

重构与软件开发过程

重构起初作为极限编程(XP)的一部分被人们采用,XP中融合了一组不太常见而又彼此关联的实践,例如持续集成、自测试代码以及重构。XP是最早的敏捷软件开发方法之一。引领了敏捷的崛起。然后要真正以敏捷的方式运作项目,团队成员必须在重构上有能力、有热情,采用的开发过程必须与常规的、持续的重构相匹配。

重构的第一块基石是自测试代码。应该有一套自动化的测试,可以频繁地运行它们,并且在编程过程中犯了任何错误,会有测试失败。

如果一支团队想要重构,那么每个团队成员都需要掌握重构技能,能在需要时开展重构,而不会干扰其他人的工作。自测试的代码也是持续集成的关键环节,所以这三大实践–自测试代码、持续集成、重构–彼此之间有着很强的协同效应。

有着三个核心实践打下的基础,才谈得上运用敏捷思想的其他部分。持续交付确保软件始终处于可发布的状态,很多互联网团队能做到一天多次发布,靠的正是持续交付的威力。即便不需要如此频繁的发布,持续集成也能帮我们降低风险,并使我们做到根据业务需要随时安排发布,而不受技术的局限。有了可靠的技术根基,我们能够极大地压缩"从好点子到生产代码"的周期时间,从而更好地服务客户。

重构与性能

重构可能使软件运行更慢,但它也使软件的性能优化更容易。

关于性能,有一个很有趣的事情:如果对大多数程序进行分析,就会发现它把大半时间都耗费在一小半代码身上。如果你一视同仁地优化所有代码,90%的优化工作都是白费劲的,因为优化的代码大多很少被执行。所以如果缺乏对程序的认识而花费时间,那么这些时间就都被浪费掉了。

更好地性能提升法是利用上述的90%统计数据,编写构造良好的程序,不对性能投以特别关注,直至进入性能优化阶段—那通常是在开发后期。一旦进入该阶段,再遵循特定的流程来调优程序性能。

一个构造良好的程序可以从两方面帮助这一优化方式。首先,让我们有比较充裕的时间进行性能调整;其次,面对构造良好的程序,在进行性能分析时便有较细的粒度。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值