何谓重构
- 对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可理解性,降低其修改成本。
- 重构提供了一种更高效且受控的代码整理技术
- 和性能优化不同,后者往往使代码较难理解,但为了性能,你不得不那么做
为何重构
-
重构改进软件设计
- 当人们只为短期目的,或是在完全理解整体设计之前,就冒然修改代码,程序将逐渐失去自己的结构,程序员越来越难通过阅读源码而理解原来的设计。
- 代码结构的流失是累积性的。越难看出代码所代表的设计意图,就越难保护其中设计,于是该设计就腐败得越快。
- 你所做的就是让所有东西回到应处的位置上。经常性的重构可以让代码维持自己该有的形态。
- 消除重复代码,确定所有事物和行为在代码中只表述一次。
-
重构使软件更容易理解
- 代码能够自我表达用途
- 尽量把该记住的东西写到程序中
-
重构帮助找到bug
-
重构提高编程速度
- 良好的设计是快速开发的根本
何时重构
- 不应该为重构而重构,你之所以重构,是因为你想做别的什么事,而重构可以帮助你把那些事做好。
- 添加功能时重构。代码的设计无法帮助我轻松添加我所需要的特性。
- 修补错误时重构。
- 复审代码时重构。
我们希望程序:
- 容易阅读;
- 所有逻辑都只在唯一地点指定;
- 新的改动不会危及现有行为;
- 尽可能简单表达条件逻辑;
怎么对经理说
- 技术复审是减少错误,提高开发速度的一条重要途径
- 大多数重构都为程序引入更多间接层, 重构往往把大型对象拆成多个小型对象,把大型函数拆成多个小型函数,但是,间接层是一把双刃剑。
- 间接层的作用:
- 允许逻辑共享
- 分开解释意图和实现
- 隔离变化
- 封装条件逻辑
- 根据情况,加入或删除间接层
重构的难题
- 访问数据库的分隔层
- 修改接口
- 如果某个函数的所有调用者都在你的控制之下,你可以随意修改
- 问题在于需要修改的接口被那些“找不到,即使找到也不能修改”的代码使用
- 对于已发布接口(published interface)的修改,需要一个更复杂的流程
- 让旧接口调用新接口,旧接口标记为deprecated
- 难以通过重构手法完成的设计改动
- 何时不该重构
- 当你应该重写所有代码时。有时候代码实在太混乱,重构不如重写一个来的简单。
- 重写的一个清楚信号:现有代码根本不能正常运作。
- 重构,代码最起码能够在大部分情况下正常运作。
- 如果项目接近最后期限,应避免重构。
- 重构与设计
- 重构肩负一项特殊使命:它和设计彼此互补。
- 事先做好设计,可以节省返工的高昂成本,但一种设计很难做到以不变应万变。
- 重构可以让你通过一条不同的途径来应付变化带来的风险。如果可以比较容易的将一个简单方案重构成一个灵活的方案,那么你只需要实现㔓的简单方案就行了。
- 重构与性能
- 不应该为了提高设计的纯洁性而忽视性能,把希望寄托于更快的硬件身上也绝非正道
- 重构虽然可能使软件运行更慢,但它也使软件的性能优化更容易。首先,可以让你有更多时间在性能优化上,因为添加功能更容易;其次,面对构造良好的程序,在性能分析时便有较细的粒度,性能的调整也比较容易,因为代码更清晰。
- 编写软件的时间预算法:给每个组件预先分配一定资源(时间和执行轨迹),每个组件绝对不能超出自己的预算。
- 大半程序运行时间耗费在一小半代码身上,所以,对性能的优化不能所有代码一视同仁。通过工具,分析出性能热点,把注意力集中在热点上。