重构——代码中的坏味道

Duplicated Code(重复代码)

  • 同一个类的两个及多个函数含有相同的表达式

    采用Extract Method提炼出重复代码,让其他函数调用被提炼的那一段代码。

  • 两个互为兄弟的子类内含相同表达式

    对两个类使用Extract Method,然后对被提炼出来的方法使用Pull Up Method,将它推入超类。

  • 两个毫无相关的类出现重复代码

    对其中一个使用Extract Class,将重复代码提炼到一个独立类中,然后在另一个类中使用这个新类。

Long Method(过长函数)

最终效果:每当感觉需要注释说明的时候,就应该把需要说明的东西写进一个函数,并用其用途来命名。

正常情况下,使用Extract Method就可以直接提炼某一块函数。如果函数含有大量的参数和临时变量,首先运用Replace Temp With Query消除临时变量,Introduce Parameter Object和Preserve Whole Object可以将过长的参数列表变得简单。

Long Method(过长函数)

最终效果:每当感觉需要注释说明的时候,就应该把需要说明的东西写进一个函数,并用其用途来命名。

正常情况下,使用Extract Method就可以直接提炼某一块函数。如果函数含有大量的参数和临时变量,首先运用Replace Temp With Query消除临时变量,Introduce Parameter Object和Preserve Whole Object可以将过长的参数列表变得简单。

Large Class(过大的类)

如果想利用单个类做太多事情,其中就会出现很多实例变量,往往导致Duplicate Code出现。使用Extract Class将几个变量提炼至新类。

先确定客户端如何使用它们,然后运用Extract Interface为每一种使用方式提炼出一个接口,有利于清楚的知道如何分解这个类。

Long Parameter List(过长参数列)

函数需要太多参数会造成前后不一致,不易使用,而且一旦需要更多数据,就不得不修改它。如果向已有对象发出一条请求就可以取代一个参数,可以运用Replace Parameter with Method方法。

Divergent Change(发散式变化)

如果某个类经常因为不同的原因在不同的方向上发生变化,比如,替换某一个工具类,需要在一个类的好几处函数中修改。针对某一外界变化的所有相应修改,都应该只发生在单一类中,而这个类中的所有内容都应该反应这个变化。

Switch Statements

何时该用switch,何时该用多态。如果在单一函数下有些选择示例,就可以继续使用switch。如果在多个地方需要同样的switch语句时就需要修改为多态来解决问题。

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

某个实例变量仅为某种特殊情况而定,这样的代码让人不易理解。有些字段只在使用该函数时生效,其他情况下只会让人迷惑。利用Extract Class把相关变量和相关函数提炼到一个独立类中。

Comments(过多的注释)

通常会有这种情况:看到一段代码有着常常的注释,是对某段复杂代码加以解释,之所以存在原因是因为代码很糟糕。当看到注释时,第一反应应该是能否用重构去除代码复杂性。

Data Class(纯稚的数据类)

只是一个数据容器,被其他类操控。自身数据的修改或者操作,尝试以Move Method把那些行为搬移到Data Class中。