在讲模板模式原理前,咱们按照管理,先来个生活中例子。茶馆须要开发一个自动的泡咖啡和泡茶的程序。java
本文出自:《凯哥学设计模式》系列教程中的模板模式一算法
咱们先来看看泡咖啡和泡茶的步骤:设计模式
咱们根据上图写代码实现:ide
泡咖啡类,以下图:测试
泡茶类以下图:spa
测试类:设计
运行结果:orm
很简单。也很容易写出来。写出来很清楚。继承
从上图中,能够发现,两个流程几乎是同样的套路(步骤)。其中,不变的部分:水烧开、倒入杯子、送给客人。这三步是不变的。教程
变化的是:冲咖啡仍是泡茶叶;加糖/牛奶仍是加柠檬这两个步骤是变化的。
项目进化第一个版本:
咱们将不变的抽取出来,放到一个公共的类中。HotDrink。而后让coffe和tea都继承公共的类。获得的类图以下:
hotdrink超类代码以下:
项目进化第二个版本:
通过分析,咱们发现,两个流程的还有相同的地方:
1.两个流程的步骤都同样(都是五个步骤的);
2.不管泡茶仍是泡咖啡都是brew操做;
3.不管加糖仍是加柠檬都是添加调料的。
因此,咱们对项目在进行一次提取:
咱们将操做流程也提取到超类中,将2和3操做也放到超类中。让子类具体实现。因此获得类图以下:
咱们来看看此次hotdrink类里面:
public abstract class HotDrink {
public final void prepareRecipe(){
boilWater();
brew();
pourInCup();
addCondiments();
send();
}
protected abstract void addCondiments();
protected abstract void brew();
private final void boilWater() {
System.out.println("一.烧水");
}
private final void pourInCup() {
System.out.println("三.倒入杯中");
}
咱们发现,在prepareRecipe方法和boilWter、pourInCup、send这四个操做都添加了final关键字来修改。这是为何呢?
从上面分析,咱们知道,都是五个步骤,并且五个步骤中的三个步骤(烧水、倒入杯中、送客人)也是固定不变的。那么,在Java中,固定不变的这个怎么表示呢?对了,就使用fianl这个关键字修饰就能够了。这样,就能够放置子类不能随便修改步骤(好比由五步变成三步),已经规定的不能在修改了。好比烧水这个不烧了,这样是不行的。
咱们来看看,热饮coffee和tea的类:
hotDrinkTea:
测试方法:
运行结果:
咱们对项目进化进行复盘总结,能够获得:
所谓的模板模式:封装了一个算法的步骤,并容许子类为一个或多个步骤方法提供实现。模板模式,可使子类在不改变算法结构(如上面的五步)的状况下,从新定义算法中某些步骤(如上面的第二步和第四步)
模板模式类图以下:
类图说明:
1:是一个抽象类(如:hotDrink)
2:有个模板方法。这个模板方法是final的(如:prepareRecipe方法)
3:由三种方法:
AbsOperation:抽象的方法(泡咖啡、加牛奶)
concreteOp:具体的方法(如烧水。能够是final的也能够不是)
hook:钩子。能够选的子类能够覆盖父类的方法。
咱们来演示下带有hook的。
好比,如今有了新需求,客户能够本身选择需不须要添加调料。这个怎么作呢?
本文来源:
凯哥Java(kaigejava)
凯哥我的博客:www.kaigejava.com
咱们重新定义模板:
tea实现了该模板类,而且不加柠檬的:
测试运行:
结果: