1. Pull Up Field (提升值域)
解释:
如果发现每个子类都拥有相同的某个值域, 那么使用 Pull Up Field 将这个值域提升到父类中去.
冲动前:
冲动后:
2. Pull Up Method (提升函数)
解释:
如果每个子类都有相同的某个函数, 这个函数做同样的事情, 而且结果也相同, 那么使用 Pull Up Method 将这个函数提升到父类中去.
冲动前:
冲动后:
3. Pull Up Constructor Body (提升构造函数)
解释:
特别要注意每个子类中重复的代码, 如果可能的话尽量将它们提炼成方法并搬到父类中去. 对于子类的构造函数, 我们需要找出相同的部分, 用这些相同的部分组成父类的构造函数.
如下面的例子, 如果不光 Salesman, 还有 Engineer 等等类别的员工在构造他们的时候都需要 name 和 level 属性, 可以考虑使用 Pull Up Constructor Body 将设置这两个属性提升到父类的构造函数中去.
冲动前:
02 | public string Name { get ; set ;} |
03 | public int Level { get ; set ;} |
06 | class Salesman : Employee |
08 | public string Hobby { get ; set ;} |
10 | public Salesman( string name, int level, string hobby) |
冲动后:
02 | public string Name { get ; set ;} |
03 | public int Level { get ; set ;} |
05 | public Employee( string name, int level) |
12 | class Salesman : Employee |
14 | public string Hobby { get ; set ;} |
16 | public Salesman( string name, int level, string hobby): base (name,level) |
4. Push Down Method (降低函数)
解释:
父类里有某个函数只与一部分子类有关, 并不是与所有的子类都有关, 使用 Push Down Method 重构手段将这些函数放到使用它们的子类中去, 而不要放到父类中.
冲动前:
冲动后:
5. Push Down Field (降低值域)
解释:
与 Push Down Method 描述的问题类似, 父类中如果某个值域并不是对于每个子类都有用的, 应该把它放到需要它的子类中去.
6. Extract Subclass (提炼子类)
解释:
我们产生了类的一些实例, 但并不是每个实例都用得到类中所有的特性, 往往这是类中功能设计过多的原因造成的. 尝试从这个类中提炼出一些子类, 子类中的功能应该划分得很明确.
7. Extract Superclass (提炼父类)
解释:
如果你发现有两个类, 他们有很多相同的特性, 尝试找出两个类中相同的特性, 如果你能找到一个合适的理由让这两个类继承自一个父类, 从而你可以提炼出这个父类, 父类中包含那两个类中相同的部分.
8. Extract Interface (提炼接口)
解释:
类与类之间经常会相互调用, 比如 ClassA 的某个函数里需要 ClassB 里的某个值域或者某个函数的返回值, 因此我将整个 ClassB 作为参数传递给 ClassA 的这个函数, 这意味着 ClassA 的这个函数能够调用 ClassB 里所有的功能, 可不可以给 ClassA 的这个函数划定一个特定的职能呢? 让它只能做某些事情, 而避免其它 "越权行为". 有句话常被人说起 ——使用接口来降低耦合性, 这就是 Extract Interface 的功劳.
这条重构手段经常被使用到, 主要解决类对另一个类的依赖问题, 降低了耦合性.
冲动前:
06 | public void Translate() |
14 | public string GetWeather(Xml xml) |
18 | //other code, but without xml object |
冲动后:
11 | public void Translate() |
19 | public string GetWeather(IOperation operation) |
23 | //other code, but without xml object |
注意代码高亮的那行已经变成调用接口, 而不是仅依赖调用 Xml 类的实例, 对于单个类实现这样的接口并不是很有价值, 如果很多类都实现了同样的接口, 这将是很有用的事情.
9. Collapse Hierarchy (去掉不必要的继承关系)
解释:
庞大的继承体系很容易变得复杂, 理清父类与子类它们各自的职能是非常重要的, 你很有可能会发现不必要的子类, 那么使用 Pull Up Field 和 Pull Up Method 将它干掉.
10. Replace Inheritance with Delegation (用委派取代继承)
解释:
如果你想让 ClassA 使用某个类 (如 ClassB) 的某个函数, 就让 ClassA 继承自 ClassB, 这将是一个多么糟糕的设计! 你可以在 ClassA 中包含一个 ClassB 的值域, 通过这个值域调用你需要的函数, 这个值域就是"委派", 而你这时可以去掉 ClassA 和 ClassB 之间不该存在的继承关系了.
11. Replace Delegation with Inheritance (用继承代替委派)
解释:
这一条与 Replace Inheritance with Delegation 正好相反, 如果你需要使用委派中的所有函数, 这时你就应该想想它们之间是不是存在继承关系.