| 重构的理由 | 说明 |
|---|---|
| 代码重复 | David Parnas:复制粘贴即设计之缪 |
| 冗长的子程序 | 面向对象编程,很少会需要用到长度超过一个屏幕的子程序 改善系统的方法之一就是提升其模块性 增加定义完善、命名准确的子程序,让它们各自集中做好一件事情 |
| 循环太长或嵌套太深 | 循环内部的复杂代码常常具备转换为子程序的潜质 有助于对代码的分解,减少循环的复杂性 |
| 内聚性太差的类 | 如果看到某个类包含了许多彼此无关的任务 那么这个类就该被拆分成多个类 每个类负责一组具有内在的相互关联的任务 |
| 类的接口未能提供层次一致的抽象 | 提供层次一致对外接口 |
| 拥有太多参数的参数列表 | 长长的参数列表是在警告程序员的子程序接口抽象未经斟酌 |
| 类的内部修改往往被局限于某个部分 | 你发现要么修改类的这一部分,要么修改另一部分, 但极少的修改会同时影响类中的两个部分 这就表明该类应该根据相互独立的功能被拆分为多个类 |
| 变化导致对多个类的相同修改 | 如果发现常常对同组类进行修改 这表明这些类种的代码应当被重新组织 使修改仅影响到其中的一个类 |
| 对继承体系的同样修改 | 每次为某个类添加派生类时 都会发现不得不对另一个类做同样的操作 这就是一种特殊的相同修改,应该避免这种情况 |
| case 语句需要做相同的修改 | 如果不得不在程序的多个部分里对类似的一组case语句 做出相同的修改,那么就应当问问自己 使用继承是否更明智的选择 |
| 同时使用的相关数据 未以类的方式进行组织 | 如果常常对同样一组数据进行操作 应该将这些数据及其操作组织到一个类里面 |
| 成员函数使用其他类的特征 比使用自身类的特征还要多 | 这一状况暗示着这一子程序应该被放到另一个类中 然后在原来的类里调用 |
| 过多使用基本数据类型 | 基本数据类型可用于表示真实世界中实体的任意数量 如果程序中使用了整型表示某种常见的实体如货币 请考虑创建一个简单的Money类 这样编译器就可以对Money变量进行类型检查 你也可以对赋给Money的值添加安全检查等功能 |
| 某个类无所事事 | 代码的重构可能会导致某个已有的类无事可做 如果一个类看起来名不符实 那么应将该类的功能转交给其他的类,然后彻底去掉 |
| 一系列传递流浪数据的子程序 | 把数据传递给某个子程序,仅仅就为了让该子程序 把数据转交给另一个子程序,这样传来传去的数据 被称为 流浪数据 ,这样做也不是不行 但要问问自己,如此传递特征数据 是否与每个字程序接口所表示的抽象概念一致 如果这些子程序接口的抽象概念相同,OK 如果不是这样,那么就像写办法让各子程序接口更加一致 |
| 中间人对象无事可做 | 如果看到某个类种的绝大部分代码只是去调用其他 类中的成员函数,请考虑是否应该把这样的中间人去掉 转而直接调用其他的类 |
| 某个类同其他类关系过于密切 | 如果需要使程序具备更强的可管理型 并最大限度打的减少更改代码对周围的连带影响 那么封装可能是最强有力的工具了 |
| 子程序的命名不恰当 | 如果一个子程序的名字取得不好 请改变其定义的名字 |
| 数据成员被设置为公用 | 把数据成员设置为公用绝对是一个糟糕的主意 这样会模糊接口和实现之间的界限 违背了封装的原则,限制了类在未来可以发挥的灵活性 因此,请认真考虑把public数据成员藏在访问器子程序背后 |
| 派生类仅仅使用了基类的一小部分成员函数 | 这样的情况表明,这一派生类的创建仅仅是由于 基类碰巧有了该类所需要的子程序 而不是出于逻辑上的派生关系 因此应当考虑进行更完善的封装: 把派生类对于基类的关系从 is-a 转变为 has-a 即把基类转换为原来的派生类的数据成员 然后仅仅为原来的派生类提供所需要的成员函数 |
| 用注释来掩饰拙劣的代码 | 不要为拙劣的代码编写文档,应当重写代码 |
| 使用了全局变量 | 当你再度遇到某段使用了全局变量的代码时 请花点时间来重新检查一下这些代码 你应该知道如何将全局变量隔离出来 通过访问器子程序来调用这些数据 |
| 在子程序调用前使用设置代码,调用后使用收尾代码 | 只要发现在一个子程序调用之前使用了设置代码 或者在调用后使用了收尾代码 就应该问问自己 这个子程序的接口是否体现了正确的抽象 |
| 程序包含的某些代码似乎在将来某个时候才会被用到 | 超前设计常常会遭遇很多可预见的问题 |