1. 概述
定义一个操作中的算法的骨架,而将步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义算法的某些特定步骤。
2. 模式中的角色
2.1 抽象类(AbstractClass):实现了模板方法,定义了算法的骨架。
2.2 具体类(ConcreteClass):实现抽象类中的抽象方法,已完成完整的算法。
3.模板方法模式的实现要素
准备一个抽象类,将部分逻辑以具体方法的形式实现,然后声明一些抽象方法交由子类实现剩余逻辑,用钩子方法
给予子类更大的灵活性。最后将方法汇总构成一个不可改变的模板方法。
案例。泡茶和泡咖啡。
/**
* 抽象基类,为所有子类提供一个算法框架
* 提神饮料
*/
abstract class RefreshBeverage {
/**
* 制备饮料的模板方法
* 封装了所有子类共同遵循的算法框架
*/
public final void prepareBeverageTemplate(){
//步骤1 将水煮沸
boilWater();
//步骤2 炮制饮料
brew();
//步骤3 将饮料倒入杯中
pourInCup();
//步骤4 加入调味料
if(isCustomerWantsCondiments()) {
addCondiments();
}
}
/**
* Hook,钩子函数,提供一个默认或空的实现
* 具体的子类可以自行决定是否挂钩以及如何挂钩
* 询问用户是否加入调料
*/
protected boolean isCustomerWantsCondiments(){
return true;
}
/**
* 基本方法,将水煮沸
*/
private void boilWater(){
System.out.println("将水煮沸");
}
private void pourInCup(){
System.out.println("将饮料倒入杯中");
}
/**
* 抽象的基本方法,炮制饮料
*/
protected abstract void brew();
/**
* 抽象的基本方法,加入调料
*/
protected abstract void addCondiments();
}
public class Coffee extends RefreshBeverage{
@Override
protected void brew() {
System.out.println("用沸水冲泡咖啡");
}
@Override
protected void addCondiments() {
System.out.println("加入糖和牛奶");
}
}
/**
* 具体子类,提供了制备茶的具体实现
*/
public class Tea extends RefreshBeverage{
@Override
protected void brew() {
System.out.println("用80度的热水浸泡茶叶5分钟");
}
@Override
protected void addCondiments() {
System.out.println("加入柠檬");
}
@Override
protected boolean isCustomerWantsCondiments() {
return false;
}
}
public class RefreshBeverageTest {
public static void main(String[] args){
System.out.println("制备咖啡。。。");
RefreshBeverage coffee=new Coffee();
coffee.prepareBeverageTemplate();
System.out.println("咖啡好了!");
System.out.println("**************************");
System.out.println("制备茶。。。");
RefreshBeverage tea=new Tea();
tea.prepareBeverageTemplate();
System.out.println("茶好了");
}
}