1. 问题及方案
- 字段位置不正确:Pull Up Field、Pull Down Field;
- 函数位置不正确:Pull Up Method、Pull Down Method;
- 构造函数:Pull Up Constructor Body(向上)、Replace Constructor with Factory Method;
- 函数大体相同、细节不同:Form Template Method;
- 改变继承体系:Extract Subclass、Extract Superclass、Extract Interface;
- 继承体系部分类无用:Collapse(瓦解) Hierarchy(层次结构);
- 委托替代继承:Replace Inheritance with Delegation;
- 继承替代委托:Replace Delegation with Inheritance;
2. Pull Up Field/Method(字段/函数上移)
将多个子类的相同字段/函数移到超类。
3. Pull Down Field/Method(字段/函数下移)
超类的字段/函数只与部分(而非全部)子类有关,移动到相关子类中。
4. Pull Up Constructor Body(构造函数本体上移)
多个子类的构造函数相同,将主体移动到超类构造函数中,并在子类中调用它。
5. Replace Constructor with Factory Method(使用工厂方法替代构造函数)
由于无法将构造函数本体下移,故改为使用工厂方法模式。
6. Extract Subclass(提炼子类)
问题:类中的某些特性只被某些(而非全部)实例使用。
新建一个子类,移动特性到子类中。ps
:Extract Class 是另一种选择,两者抉择之处在于委托和继承之间的选择。
7. Extract SuperClass(提炼超类)
为两个相似的类建立一个超类,将相同特性移至超类。
8. Extract Interface(提炼接口)
多个类有相似的行为,或多个类的接口有相似部分,将相同的行为提炼到一个独立的接口中。
9. Collapse Hierarchy(折叠继承体系)
问题:超类和子类之间无太大区别。
将它们合为一体。
10. Form Template Method(塑造模板函数)
问题:子类的某些函数以相同顺序执行类似操作,细节有所不同。
将这些操作分别放进独立函数中,并保持相同签名。而后将原函数提炼到超类中。ps
:即模板方法模式。
11. Replace Inheritance with Delegation(以委托取代继承)
问题:某个子类只使用超类的一部分,或根本不需要继承而来的数据。
在子类中新建一个字段引用超类,调整子类函数,而后让它调用超类,最后去除两者之间的继承关系。ps
:此处的委托其实应该理解为委托调用关系,即依赖关系,而非 C# 的委托。
12. Replace Delegation with Inheritance(以继承取代委托)
问题:两个类之间使用委托关系,并经常为了整个接口(即所有函数)编写许多极其简单的委托函数。
让委托类继承被委托类。ps
:
- 该重构手法与 Replace Inheritance with Delegation 恰恰相反。
- 如果你并没有使用被委托类的所有函数,就不该使用该重构手法。
- 被委托对象被不止一个对象共享,而且被委托对象是可变的,此时就不该使用该重构手法。
参考
- 《重构-改善既有代码的设计》(第11章)