模板方法

简介

模板方法,顾名思义,就是个方法,其实质是对算法的封装。通过继承的方式,将公共的代码封装在父类中,实现代码的复用,将变化的部分抽象成抽象方法,交给子类去实现。通过模板方法,我们就算法封装成先干什么、后干什么,最后干什么,子类实现只需提供对变化部分的具体实现,具体步骤无需在重新定义。一般情况,为了更好的保护程序,不被子类篡改算法,模板方法会用final 修饰。

实现

《Head First设计模式》举了一个冲茶和冲咖啡的例子,由于他们包含相同的部分(比如烧开水,装入杯子),但是又包含不同的部分(泡法、加入食材),因此不变的代码可以复用,变化的代码交给子类定义,实现代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public abstract class CaffeineBeverage {
final void prepareRecipe() {
boilWater();
brew();
pourInCup();
addCondiments();
}

protected abstract void brew();

protected abstract void addCondiments();

private void pourInCup() {
System.out.println("Pouring into cup");
}

private void boilWater() {
System.out.println("Boiling water");
}
}

子类需要继承父类,提供具体的实现

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Tea extends CaffeineBeverage {

@Override
protected void brew() {
System.out.println("Steeping the tea");
}

@Override
protected void addCondiments() {
System.out.println("Adding Lemon");
}

}

定义

书上定义为:

在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。

类图为:

扩展

钩子hook

在定义的父类中,我们可以定义一个空方法。当子类需要使用时,可以去覆盖该方法,当没覆盖时,就什么都不干。

好莱坞原则

该原则有点类似前面的依赖倒置原则

别调用(打电话)我们,我们会调用(打电话)你。

应用

模板方法一个典型的例子就是定义排序算法,比如冒泡排序、插入排序、选择排序等等。

源码案例

双亲委派模型、AQS算法、spring的refresh方法

实际开发

计算引擎消息架构、报表打印实现