模板方法定义了一个算法的步骤,并允许子类为一个或多个步骤提供实现。
# 模板方法模式
模板方法模式在一个方法中定义一个算法的骨架,将一些步骤延迟到子类中。
模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤
# 何时使用 WHEN
子类必须提供算法中某个方法或者步骤的实现时
- 如果算法这个部分是可选的,使用钩子
# 模板方法实现
为了防止子类改变模板方法中的算法,可以将模板方法声明为 final
abstract class AbstractClass {
final void templateMethod() { //模板方法,final,不可修改
primitiveOperation1();
primitiveOperation2();
hook(); // 钩子
concreteOperation();
}
abstract void primitiveOperation1(); // 两个原语操作,具体子类必须实现他们
abstract void primitiveOperation2();
final void concreteOperation() { // 具体方法定义在抽象类中,子类无法覆盖
...
}
void hook() {} // 钩子函数,默认只有空的实现
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 钩子 hook
钩子是一种被声明在抽象类中的方法,只有空的或者默认的实现,钩子可以让子类有能力对算法进行挂钩。
- 有了钩子,可以让抽象类提供一个默认的实现,子类可以决定要不要覆盖方法
- 钩子可以作为条件控制,影响抽象类的算法流程
- 子类有机会对模板方法中某些即将发生的步骤做出反应
# 设计原则
好莱坞原则:高层组件对待低层组件的方式是:别调用我们,我们会调用你
- 允许低层组件将自己挂钩到系统上,但是高层组件会决定什么时候、和怎样使用这些低层组件。
依赖倒置原则:尽量避免使用具体类,而多使用抽象