电子书下载地址:https://download.csdn.net/download/qq_28713413/10873077
重构与性能
不赞成为了提高设计的纯洁性而忽视性能,把希望寄托于更快的硬件身上也绝非正道。
虽然重构可能使软件运行更慢,但它也使软件的性能优化更容易。除了对性能有严格要求的实时系统,其他任何情况下“编写快速软件”的秘密就是:首先写出可调的软件,然后调整它以求获得足够速度。
代码的坏味道
- 重复代码;
- 过长的函数;
- 过大的类;
- 过长的参数列;
- 发散式变化:
- 霰弹式修改:如果需要修改的代码散布四处,不但很难找到它们,也很容易忘记某个重要的修改;
- 依恋情结:解决原则:将总是一起变化的东西放在一起。数据和引用这些数据的行为总是一起变化的。
- 数据泥团;
- 基本类型偏执;
- switch惊悚现身:
- 平行继承体系:
- 冗赘类:你所创建的每个类,都得有人去理解它、维护它,这些工作都是要花钱的。如果一个类的所得不值其身价,它就应该消失。
- 夸夸其谈未来性:
- 令人迷惑的暂时字段:
- 过度耦合的消息链:
- 中间人:
- 狎昵关系:两个类不要太过于亲密;
- 异曲同工的类:两个类做同样的事情,有着不同的签名;
- 不完美的库类:
- 纯稚的数据类:
- 过多的注释;
构筑测试体系
自测试代码
每个类都应该有一个测试函数,并以它来测试自己这个类。
确保所有测试都自动化,让它们检查自己的测试结果。
一套测试就是一个强大的bug侦测器,能够大大缩减查找bug所需时间。
单元测试和功能测试。
考虑可能出错的边界条件,把测试火力集中在那儿。
重构列表
重构的纪录格式
- 名称;建造一个重构词汇表,名称很重要。
- 简短概要:简单介绍重构手法的适用情景,以及它所做的事情。
- 动机:为什么需要这个重构?什么情况下不该使用这个重构。
- 做法:简明扼要介绍如何进行此重构。
- 范例:简单例子说明重构手法如何运作。
重新组织函数
- 提炼函数;
- 内联函数;
- 内联临时变量;
- 以查询取代临时变量;
- 引入解释性变量;
- 分解临时变量;
- 以函数对象取代函数;
- 替换算法;
对象之间的搬移特性
- 搬移函数;
- 搬移字段;
- 提炼类;
- 将类内联化;
- 隐藏委托关系;
- 移除中间人;
- 引入外加函数;
- 引入本地扩展;
重新组织数据
?
简化条件表达式
- 分解条件表达式:
- 合并条件表达式:
- 合并重复的条件片段:
- 移除控制标记:在一系列布尔表达式中,某个变量带有“控制标记”的作用,以break语句或return语句取代控制标记。
- 以卫语句取代嵌套条件表达式:
- 以多态取代条件表达式:
简化函数调用
- 函数改名:给函数起个号名称,准确表达它的用途。
- 添加参数:某个函数需要从调用端得到更多信息;为此函数添加一个对象参数,让该对象带进函数所需要的信息。
- 移除参数;
- 将查询函数和修改函数分离;
- 另函数携带参数:建立单一函数,以参数表达那些不同的值;
- 以明确函数取代参数:针对该参数的每一个可能值,建立一个独立函数;
- 保持对象完整:
- 以函数取代参数:
- 引入参数对象:
- 移除设值函数:
- 隐藏函数:
- 以工厂函数取代构造函数:
- 以异常取代错误码:
- 以测试取代异常:
大型重构
对于一个长时间、大负荷运转的系统来说,将业务逻辑和用户界面隔离开来是至关重要的。
- 梳理并分解继承体系:建立两个继承体系,并通过委托关系让其中一个可以调用另一个;
- 将过程化设计转化成对象设计:你手上有一些传统过程化风格的代码;将数据纪录变成对象,将大块的行为分成小块,并将行为移入相关对象中。
- 将领域和表述/显示分离:某些GUI类之中包含了领域逻辑;将领域逻辑分离出来,为它们建立独立的领域类;
- 提炼继承体系:建立继承体系,以一个子类表示一种特殊情况;