移动语句、提炼函数
查询函数和修改函数分离
移除设值函数
以查询取代变量函数组合成类
神秘命名 | 表意不准确 | 以用途命名 改变函数声明、变量改名、字段改名 |
重复代码(Duplicated Code) | 相似的处理逻辑 | 提炼函数、移动语句、函数上移 |
过长函数(Long Method) | | 提炼函数(常用)、以查询取代临时变量、 引入参数对象、保持对象完整性、以命令取代参数(消除一些参数)、 分解条件表达式、以多态取代条件表达式(应对分支语句)、 拆分循环(应对一个循环做了很多事情) |
过大的类(Large Class) | fat class | 提炼超类、以子类取代类型码 |
过长参数列(Long Parameter List) | 参数过多 | 查询取代参数、保持对象完整、引入参数对象、移除标记参数、函数组合成类 |
发散式变化(Divergent Change) | 一个类受多种变化的影响 | 拆分阶段、搬移函数、提炼函数、提炼类 |
霰弹式修改(Shotgun Surgery) | 一种变化引发多个类相应修改 | 搬移函数、搬移字段、函数组合成类、函数组合成变换、 拆分阶段、内联函数、内联字段、组合优于类继承 |
依恋情结(Feature Envy) | 函数对某个类的兴趣高过自己所处类的兴趣 | 搬移函数、提炼函数 |
数据泥团(Data Clumps) | 相同的若干项数据出现在不同地方,这些绑在一起出现的数据应该有属于它们自己的对象 | 提炼类、引入参数对象、保持对象完整性 |
基本类型偏执(Private Obsession) | 很多人不愿意在小任务上运用小对象 | 以对象取代基本类型、以子类取代类型码、以多态取代条件表达式 |
switch惊悚现身(Switch Statements) | switch语句会在很多地方重复出现,一改则需全改 | 多态取代条件表达式 |
平行继承体系(Parallel Inheritance Hierarchies) | 当你为某一个类增加子类时,也必须为另一个类相应增加一个类 | |
冗赘类(Lazy Class) | 如果一个类不值得存在,那就让它消失 | 内联函数、内联类、折叠继承类 |
夸夸其谈的未来星(Speculative Generality) | 预留的无用的抽象类,无用的抽象参数 | 不过度设计 叠继承体系、内联函数、内联类、改变函数声明、移除死代码 |
令人迷惑的暂时字段(Temporary Field) | 类中某个字段只为某些特殊情况而设置 | 命名准确,json |
过长的消息链(Message Chains) | 用户向一个对象请求另一个对象,然后再向后者请求另一个对象 | 隐藏委托关系、提炼函数、搬移函数 |
中间人(Middle Man) | 无用的委托,过多的中间层 | 移除中间人、内联函数 |
狎昵关系(Inappropriate Intimacy) 内幕交易 | 两个类过于亲密,一个类过于关注另一个类的成员 | 搬移函数、隐藏委托关系、委托取代子类、委托取代超类 |
异曲同工的类(Alternative Classes with DifferentInterfaces) | 不同名字的类或函数,作者相同的事 | 改变函数声明、搬移函数、提炼超类 |
不完美的库类(Incomplete Library Class) | 类库设计不可能完美 | C |
纯数据类(Data Class) | 一个类拥有一些字段以及用于访问这些字段的函数,除此之外一无长物 | 封装记录、移除取值函数、搬移函数、提炼函数、拆分阶段 |
被拒绝的遗赠(Refused Bequest) | 子类不想继承超类所有的函数和数据,只想挑几样来玩 | 修正父类,使得继承类都被用到且不被重写 委托取代子类、委托取代超类 |
过多的注释(Comments) | 注释可以带我们找到各种坏味道 | 重构,让代码更容易被理解 |
循环语句 | for foreach | 用管道(array_map、array_filter等)来取代循环 |
注释 | 代码不能清晰的表达意图 | 提炼函数、改变函数声明、引入断言 |
- 如果可变数据的值能在其他地方计算出来,这就是一个特别刺鼻的坏味道。
- 如果需要修改的代码散布四处,你不但很难找到它们,也很容易错过某个重要的修改。
- 如果你有一组总是同时出现的基本类型数据,这就是数据泥团的征兆,应该运用提炼类和引入参数对象来处理。
- 重复的switch语句【邪恶】 —— 多态给了我们对抗这种黑暗力量的武器,使我们得到更优雅的代码库。