一、重复代码

1、一个类中:提炼成一个函数

2、兄弟类中:提炼成一个函数,并且提取到父类中

3、两个不相关的类:提炼成一个函数,放到两个类中的一个类中或者一个单独的类中

二、过长函数

拆分成多个函数,将相关联的代码放在一个函数内,尽量保证每个函数只做一件事,且函数名见名之意

三、过大的类

保证每个类只做一件事,拆分成多个类

四、方法中过长的参数列

用对象做参数来减少参数个数

五、发散式变化

一个类做太多的事情了,万能类,经常因为不同的原因在不同的方向上发生变化,将会产生发散式变化,

将变化隔离,封装变化,把变化的和不变的部分分开,拆分成多个类

六、散弹式变化

一个变化引发多个类的修改,把需要修改的部分抽取出来,放到一个单独的类中

七、依恋情节

(红杏出墙的函数)使用了大量其他类的成员

函数对其他类的函数的调用比所处类还多,函数调用其他类的函数一般是需要其他类的数据,将该函数移动到它使用数据的类中,将数据和对数据的操作行为包装在一起,

具体是:如果该方法只调用了一个类的多个方法。将该方法移到调用类里。

如果该方法调用了多个类的多个方法。将该方法拆解。然后分离到调用类里

八、数据泥团

总是成堆出现在一起的数据,应该封装在一个单独的类中,比如你常常可以在很多地方看到相同的三四项数据:两个类中相同的字段、许多函数签名中相同的参数。这些总是绑在一起出现的数据真应该拥有属于它们自己的对象

九、基本类型偏执

用对象代替基本类型,并不是代替单个的基本类型,而是几个基本类型放在一起更有意义时应该使用对象,比如“电话号码”由基本号码,区号,地区等一起来描述时,就组装成对象,比每次都用基本类型字段描述更好。

十、switch 语句

大多数时候,一看到switch语句,你就应该考虑以多态来替换它。问题是多态该出现在哪儿?switch语句常常根据类型码进行选择,你要的是“与该类型码相关的函数或类”,所 以应该使用Extract Method将switch语句提炼到一个独立函数中,再以Move Method将它搬移到需要多态性的那个类里

如果一个 switch 操作只是执行简单的行为,就没有重构的必要了

十一、平行继承体系

每当为某个类增加一个子类,必须也为另一个类增加一个子类。消除这种重复性的一般策略是:让一个继承体系的实例引用另一个继承体系的实例。

十二、冗赘类

如果他不干活了,炒掉他吧。把这些不再重要的类里面的逻辑,合并到相关类,删掉旧的

十三、夸夸奇谈谈未来

我们经常会说:“我想总有一天需要做这事”,并因而企图以各样的钩子和特殊情况来处理一些非必要的事情。如果用不到,就不值得。删掉

比如某个抽象类其实没有太大作用,可以将超类和子类合为一体。将不必要的委托转移到另一个类中,并消除原先的类。如果函数的某些参数未被用上,那么就将参数移走。如果函数名称带有多余的抽象意味,就应该对它重命名,让它现实一些。简而言之就是删掉

十四、令人迷惑的临时字段

有时候你会发现:类中的某个实例变量仅为某种特定情况而设。这样的代码让人难以理解,因为你通常认为对象在所有时候都需要它的所有变量。

将这些临时变量集中到一个新类中管理

十五、过度耦合的消息链

有些时候我们在调用某个函数的时候往往会形成A->B->C->D.test(),这个时候如果你在A端,你就产生了Message Chains的坏味道。这种状态使的你客户代码在A中变成getB()->getC()->getD()->test(),这会使得客户代码在以后这些类关系发生变化的时候变得极易修改与相当不稳定。

可以使用隐藏“委托关系”,并在服务类上建立客户所需要的所有函数来打破这消息链,理论上你可以重构消息链上的任一对象。但这样做往往会让这些小对象都变成Middle Man(中间人),通常更好的做法是:查看消息链最终对象是用来干什么的,看看是否能用Extract Method把他提炼到一个独立的函数中去,再运用Move Method把这个函数推入消息链,

十六、中间人

大部分都交给中介来处理了。用继承替代委托。

十七、狎昵关系

两个类彼此使用对方的私有的东西。

可以通过“移动方法”和“移动字段”帮它们划清界限,从而减少狎昵行径。如果两个类实在是情投意合,可以把两者共同点提炼到一个安全地点,让它们坦荡地使用这个新类,从而改变从双向依赖A->B,B->A变成A->C,B->C。或者通过隐藏“委托关系”让另一个类来为它们传递相思情,

十八、异曲同工的类

相似的类,有不同接口 

那么你需要使用Rename Method将这些接口统一到一个名字,然后通过Move Method将某些行为移动到适合的类当中去,重构之后你会发现他们似乎更适合成为兄弟类,以方便你把这个共同函数推到父类当中去,这个时候你可以运用Extract Superclass来进行提炼父类。

十九、不完美的库类

包一层函数或包成新的类。

二十、纯稚的数据类

类很简单,仅有公共成员变量,或简单操作函数。

将相关操作封装进去,减少public成员变量。

二十一、被拒绝的遗贈

(继承过多)父类里面方法很多,子类只用有限几个,用代理替代继承关系

二十二、过多的注释

如果你需要注释来解释一块代码做了什么,试试将该代码抽取为一个单独的函数;如果函数已经被提炼出来,但还是需要注释来解释其行为,试着对其重新命名。当你感觉需要撰写注释时,请先尝试重构,试着让所有注释都变得多余。好代码即注释。