模版方法模式
定义: 在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模版方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
优点: AbstractClass中的templateMethod()拥有算法,并保护了算法,算法只存在一个地方,所以容易修改;对于子类来说,AbstractClass的存在,将代码的复用得到了最大化。
类图
代码
abstract class AbstractClass {
/**
*这就是模版方法,被定义成final,以免子类改变这个算法的顺序。
*/
final void templateMethod() {
//模版方法定义了一连串的步骤,每个步骤由一个方法代表。
primitiveOperation1();
primitiveOperation2();
conctreteOperation();
hook();
}
/**
*这两个方法定义成抽象,由具体的子类实现。
*/
abstract void primitiveOperation1();
abstract void primitiveOperation2();
/**
*这个具体的方法被定义在抽象类中。
*将它声明为final,这样一来子类就无法覆盖它。
*它可以被模版方法直接调用,或者被子类使用。
*/
final void concreteOperation() {
...
}
/**
*这个一个具体的方法,但什么事情都不做。
*这个方法被称为“钩子(hook)”,子类可以视情况决定要不要覆盖它们。
*/
void hook() {}
}
关于钩子(hook)
使用时机: 当子类“必须”提供算法中某个方法或步骤的实现时,就使用抽象方法;如果算法的这个部分是可选的,就用钩子。
钩子的作用:
- 钩子可以让子类实现算法中可选的部分;
- 钩子让子类能够有机会对模版方法中即将发生的(或刚刚发生的)步骤做出反应;
- 钩子能够作为条件控制,影响AbstractClass中的算法流程。
模版方法模式、策略模式对比
模版方法: 定义一个算法的大纲,子类决定如何实现算法中的某些步骤。
策略模式: 定义一个算法家族,并让这些算法可以互换,然后使用委托来决定要采用哪一个算法。策略模式使用对象组合,所组合的类实现了整个算法。