1、字段上移
修改点:两个子类拥有相同的字段
做法:将该字段移至父类
2、函数上移
修改点:有些函数,在各个子类中产生完全相同的效果
做法:将该函数移至父类
有一种特殊情况也需要这么做:子类函数覆盖了父类的,但是仍然做着相同的工作
在此重构中你可能会遇到一种情况,就是你提炼的函数调用了子类有而父类没有的函数,那么在父类中给此父类没有的函数,建立一个虚函数即可。
3、构造函数本体上移
修改点:你在各个子类中拥有一些构造函数,它们的本体几乎完全一致
做法:在父类中新建一个构造函数,并在子类构造函数中调用它。
4、函数下移
修改点:父类中的某个函数只与部分(而非全部)子类有关
做法:将这个函数移到相关的那些子类去。
5、字段下移
修改点:父类中某个字段只被部分(而非全部)子类用到
做法:讲这个字段下移到相关的子类去。
6、提炼子类
修改点:类中的某些特性只被某些(而非全部)实例用到
做法:新建一个类,将上面所说的那一部分特性移至子类
7、提炼父类
修改点:两个类有相似特性
做法:为这两个类建立一个父类,将相同特性移至超类
8、提炼接口
修改点:若干客户使用类接口中的同一子集,或者两个类的接口有部分相同
做法:将相同子集提炼到一个独立接口
意思很简单,就是将一个类里的一些业务相关的函数,或者是两个类中部分相同的函数,提取为Interface(这里不用接口用个英文的原因是在前面的文章中接口一词可能更多的可以理解为一个类的公共函数)
9、折叠继承体系
修改点:父类和子类无太大区别
做法:将它们合为一体
10、塑造模版函数
修改点:你有一些子类,其中相应的某些函数以相同顺序执行类似的操作,但各个操作的细节上有所不同
做法:将这些操作分别放进独立函数中,并保持它们具有相同的签名,于是原函数也就变得相同了,然后将原函数上移至父类
意思很简单,就是说你看见有些函数的具体操作不同,但是几个函数的组合操作顺序是一样的,那么就把它们的操作顺序提炼成函数放进父类。
11、以委托取代继承
修改点:某个子类只使用父类接口的一部分,或是根本不需要继承来的数据
做法:在子类中新建一个字段用以保存父类;调整子类函数,令它改而委托超类;然后去掉两者之间的继承关系
动机:随着需求的变化,一开始的继承关系可能在慢慢变化后,你就发现父类中的许多操作并不适用于子类
Troy:这个时候你当然可以去把这些不适用子类的方法去搞到另一个子类里,但是如果做不到,那么就将父类对象作为子类的一个对象吧,去掉继承关系,这在设计模式里面貌似可以叫桥接模式
12、以继承取代委托(看吧看吧,总是有相反的两个重构操作出现)
修改点:你在两个类之间使用委托关系,并经常为整个接口编写许多极简单的委托函数
做法:让委托类继承受托类
两条告诫:
1.如果你并没有使用受托类的所有函数。那么你可能不需要使用此方法,你可以去去除中间人,用客户端直接调用受托类,也可以把委托类和受托类之间提炼出一个超类,当然也可以提取接口
2.受托对象被不止一个其他对象共享,而且受托对象是可变的。那么这种情况下你也不应该用此重构,因为这样就无法共享数据了,数据共享是委托关系承担的一种责任,你无法把它转化为继承关系。如果受托对象不可变你才能这么做。