摘要:
概述
何为重构
- 名词定义1:对软件内部结构的一种调整,目的是爱不改变软件可观察行为的前提下,提高其可理解性,降低其修改成本
- 动词定义:使用一系列重构手法,在不改变软件可观察行为的前提下,调整其结构
为何重构
- 改进软件设计
- 使软件更容易理解
- 帮助找到Bug
- 提高编程速度
何时重构
- 三次法则:事不过三,三则重构
- 添加功能时重构:帮助理解需要修改的代码,理清代码结构;新特性的添加会更快速、流畅
- 修补错误:代码更具可读性;没清晰到让人一眼看出bug
- 复审代码:开发团队中传播知识,传递经验,获得建议;和团队进行设计复审:UML示意图展示设计,CRC卡展示软件情节;和单个开发者进行代码复审
需要重构的代码
- 难以阅读的
- 逻辑重复的
- 添加新行为使需要修改已有代码的
- 带复杂逻辑条件的
目标
- 易阅读
- 易修改
- 所有逻辑在唯一地点指定
- 新的改动不会危机现有行为
- 尽可能简单表达逻辑条件
间接层是一把双刃剑
- 将大型对象拆成多个小型对象,将大型函数拆成多个小型函数
- 缺点:一个东西分两份,增加管理难度;
- 多个委托依次依赖,程序难以阅读
- 优点:
- 父类、子类:允许逻辑共享
- 分开解释意图和实现
- 隔离变化
- 封装条件逻辑:多态消息
数据库
问题
- 程序与数据库结构紧密耦合
- 数据迁移:数据库结构改变
- 数据库模型复杂,难以控制
方案
- 对象模型和数据库模型间插入一个分割层,隔离两个模型各自的变化。
- 缺点:增加系统复杂性
- 优点:带来很大的灵活性
- 面向对象数据库:提供不同版本的对象间的自动迁移宫娥能
修改接口
- 接口,修改要特别谨慎。一旦被修改,任何事情都有可能发生
- 对象,可以允许分开修改软件模块的实现和接口,可以安全地修改对象内部实现而不影响他人
- 影响:被“找不到,或找到不能修改”的代码使用,会成为问题。即,已发布的接口
- 已发布的接口修改:旧接口调用新接口,并标记为deprecated
- 尽量少发布接口,不要公开太多的接口。在强调代码所有权上做出适当让步
- 发布接口有代价,除非真的有必要
- 不要过早发布接口
- 在throw子句中增加一个异常
何时不该重构
- 代码太混乱,不如重写一个来的简单:代码无法正常运作,或无法稳定运作
- 折中办法:“大块头软件”重构封装为良好的小型组件,逐一对组件做出“重构、重建”的决定
- 项目接近最后期限,避免重构。为时已晚。
- 重构确实可以提高生产力。如果最后没有足够的时间,通常表示应早该进行重构
重构与设计
- 互补关系
- 预先设计,避免返工成本
- 重构改变了预先设计的角色,不必确保预先设计一定是正确无误的,只需要一个足够合理的解决方案即可
- 重构让日后的修改成本不在高昂
- 软件设计得以简化。足够灵活、可靠的解决方案,成本难以估算;所有可能变化的地点都建立灵活性,会使整个系统的复杂度大大提高;最后可能这些灵活性毫无必要
- 重构是另一途径,来应付变化的风险。只需考虑:将一个简单的解决方案重构成一个灵活方案的难度?一般都“相当容易”
- 重构:更简单的设计,不损失灵活性,降低设计过程的难度和压力
重构与性能
- 不赞成为了提高设计的纯洁性而忽视性能,不将性能寄托在更快的硬件上
- 重构,可能使软件运行更慢,也可使软件的性能优化更容易
- 除了对性能有严格要求的实时系统,其他任何情况下“编写快速软件”的秘密就是:首先写出可调的软件,然后调整他以求获得足够的速度
- 编写快速软件的方法:
- 时间预算法。
- 多用于性能要求极高的实时系统。
- 分解设计时做好预算,给每个组件预先分配一定的资源(包括时间和执行轨迹),每个组件绝对不能超过自己的预算,就算拥有组件之间调度预配时间的机制也不行。
- 此方法,高度重视性能
- 持续关注法。
- 要求任何程序员在任何时间做任何事,都设法保持系统的高性能
- 通常没有太大作用,视角通常太狭隘。
- 修改只是为了提高性能,通常会使程序难以维护,继而减缓开发速度
- 一视同仁的优化所有代码。90%的优化都是白费劲,代码很少被执行,没达到应有的效果。需要对程序有清楚的认识
- 90%统计数据
- 编写构造良好的程序,不能对性能投以特别的关注,直至进入性能优化阶段(通常在开发后期)
- 首先,用一个度量工具来监控程序的运行,得到哪些地方消耗大量的时间、空间,找出性能热点所在的代码
- 注意力集中在性能热点上,较少的工作量可得到较好的成果
- 保持谨慎,应小幅度进行修改,每一步都需编译、测试、再次度量。如果性能没有提高,则撤销此次修改
- 保持“发现热点,去除热点”,直至得到满意的性能
- 构造良好的程序的帮助
- 较充裕的时间进行性能调整。构造良好的代码,可帮助更快速地添加功能,有更多的时间用在性能问题上(准确的度量则保证将时间投资在恰当的地方)
- 构造良好的程序,在性能分析时有更细的粒度。度量工具将你带到范围较小的程序段落中,性能调整更容易些。代码更加清晰,则帮助理解自己的选择,更清楚那些调整起关键作用。
- 短期看,重构可能使软件变慢,但优化阶段的软件性能调整容易,最终更易得到较好的效果。
重构缘起何处
- 优秀的程序员肯定至少会花一些时间来清理自己的代码。
- 简洁的代码比杂乱无章的代码更容易修改
- 知道自己几乎无法一开始就写出简洁的代码
- 重构可以提高生产力,对于开发灵活高效的框架很有帮助
- 重构使一门非常重要的技术,对生产性能、产品质量带来很大的影响