1 代码坏味道

1 Duplicated Code(重复代码)

现象

  1. 同一个类的两个函数含有相同的表达式。
  2. 两个互为兄弟的子类内含相同的表达式(可能其中对应的某些函数以相同顺序执行类似的操作,但在各个操作的细节上有所不同)。

重构手法

  1. Extract Method
  2. Extract Method->Pull Up Method (->Form Template Method)

2 Long Method(过长函数)

现象

  1. 一个函数所承担的事情太多,导致代码行数过长(可能有临时变量存在)。

重构手法

  1. Extract Method (->Replace Temp with Query)

3 Large Class(过大的类)

现象

  1. 一个类做了太多的事情,不符合单一职责原则,导致代码过多。

重构手法

  1. Extract Class

4 Long Parameter List(过长参数列)

现象

总体表现为一个函数的参数列表太长,可能伴随着以下两种现象:

  1. 向已有的对象发出一条请求就可以取代一个参数。
  2. 某些参数数据缺乏合理的对象归属。

重构手法

  1. Replace Parameter with Explicit Method
  2. Introduce Parameter Object

5 Divergent Change(发散式变化)

现象

  1. 某个类经常因为不同的原因在不同的方向上发生变化。

重构手法

  1. Extract Class

6 Shotgun Surgery(霰弹式修改)

现象

  1. 每遇到某种变化,都必须在许多不同的类内作出许多小修改。

重构手法

  1. Move Method->Move Field

7 Feature Envy(依恋情结)

现象

  1. 函数对某个类的兴趣高过对所驻类的兴趣。
  2. 函数中的一部分对某个类的兴趣高过对所驻类的兴趣。

重构手法

  1. Move Method
  2. Extract Method->Move Method

8 Data Clumps(数据泥团)

现象

  1. 多个类中有这相同的字段。
  2. 多个函数的签名中有着相同的字段。

重构手法

  1. Extract Class
  2. Extract Class->Introduce Parameter Object

9 Primitive Obsession(基本类型偏执)

现象

总体表现为以基本类型表示一些具有业务性质的概念,又分成两种情况:

  1. 基本类型都是独立的出现
  2. 几个基本都行总是一起出现(可能出现在函数参数列表中)

重构手法

  1. Replace Data Value with Object
  2. Extract Class (->Introduce Parameter Object)

10 Switch Statements(switch惊悚现身)

现象

代码中出现switch表达式,分以下两种场景

  1. 根据类型码来选择不同的行为。
  2. 只是单一函数中有些选择事例(可能选择条件之一是NULL)

重构手法

  1. Extract Method->Move Method->Replace Conditional with Polymorphism
  2. Replace Parameter with Explicit Method (->Introduce Null Object)

11 Parallel Inheritance Hierarchies(平行继承体系)

现象

  1. 每当为某个类增加一个子类,也必须为另一个类相应增加一个子类(Shotgun Surgery的特殊情况)

重构手法

  1. Move Method->Move Field

12 Lazy Class(冗赘类)

现象

某个类在重构后变得冗余,或者这个类是为未来变化服务的,当前并没有用。可能属于以下两种场景:

  1. 属于继承体系
  2. 属于组合体系

重构手法

  1. Collapse Hierarchy
  2. Inline Class

13 Speculative Generality(夸夸其谈未来性)

现象

某个类是为未来变化服务的,当前并没有用。可能属于以下两种场景:

  1. 属于继承体系
  2. 属于组合体系

重构手法

  1. Collapse Hierarchy
  2. Inline Class

14 Temporary Field(令人迷惑的临时字段)

现象

  1. 在一个类中,某个字段只在特定的情况下才有用,其余情况下容易令人迷惑。

重构手法

  1. Extract Class (将该字段以及使用到它的代码提取到一个新的类中,使得代码高内聚)

15 Message Chains(过度耦合的消息链)

现象

  1. 向一个对象请求另一个对象,然后在向后者请求另一个对象,…

重构手法

  1. Hide Delegate

16 Middle Man(中间人)

现象

  1. 某个类接口有一半的函数都委托给其他类。

重构手法

  1. Remove Middle Man

17 Inappropriate Intimacy(不适当的亲密关系)

现象

  1. 两个类过于亲密,花费太多时间去探究彼此的private成分。

重构手法

有以下两种重构思路:

  1. Move Method->Move Field
  2. Extract Class (将两者共同点提炼到一个新的类中)

18 Data Class(纯数据类)

现象

  1. 某些类拥有一些字段,以及对应的getter/setter函数,除此之外一无长处。这些类通常被其他类过分琐碎的操控者。
  2. 只有getter/setter函数,没有业务行为函数的类就是DDD中提到的贫血模型。在软件开发过程中,除非框架要求,应该杜绝贫血模型的出现。

重构手法

  1. Remove Setting Method(对那些不该被其他类修改的字段使用)->Move Method(把在其他类上的调用行为搬移到数据类中)

19 Comments(过多的注释)

现象

  1. 如果一段代码有着长长的注释,那么就会发现,这些注释之所以存在是因为代码很糟糕,注释本身并不是一种坏味道。

重构手法

  1. Extract Method