本文章参考:http://meigesir.iteye.com/blog/1506484
模板模式(Template Pattern)
模板模式又叫模板方式,在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
我们使用冲咖啡喝冲茶叶的过程来讲解模板模式。假设冲咖啡和冲茶叶的流程是这样的:
咖啡:1.把水煮沸 2.用沸水冲泡咖啡 3.把咖啡倒进杯子 4.加糖和牛奶
茶叶:1.把水煮沸 2.用沸水冲泡茶叶 3.把茶叶倒进杯子 4.加蜂蜜
Java实践:
1> 创建一个模板(抽象)类:Beverage(饮料)
public abstract class Beverage {
/**
* 冲泡咖啡或茶的流程
*/
public final void create() {
boilWater();//把水煮沸
brew();//用沸水冲泡
pourInCup();//倒进杯子
addCoundiments();//加糖或其它
}
public void boilWater() {
System.out.println("煮开水");
}
public abstract void brew();
public void pourInCup() {
System.out.println("倒进杯子");
}
public abstract void addCoundiments();
}
①咖啡(Coffee)
public class Coffee extends Beverage {
/**
* @see com.study.templatepattern.Beverage#brew()
*/
@Override
public void brew() {
System.out.println("用水冲咖啡");
}
/**
* @see com.study.templatepattern.Beverage#addCoundiments()
*/
@Override
public void addCoundiments() {
System.out.println("添加糖和牛奶");
}
}
②茶(Tea)
public class Tea extends Beverage {
/**
* @see com.study.templatepattern.Beverage#brew()
*/
@Override
public void brew() {
System.out.println("用水冲茶");
}
/**
* @see com.study.templatepattern.Beverage#addCoundiments()
*/
@Override
public void addCoundiments() {
System.out.println("添加蜂蜜");
}
}
写一个类测试:
public static void main(String[] args) {
Coffee coffee = new Coffee();
coffee.create();
System.out.println("-----------------------------");
Tea tea = new Tea();
tea.create();
}
运行结果:
煮开水
用水冲咖啡
倒进杯子
添加糖和牛奶
------------
煮开水
用水冲茶
倒进杯子
添加蜂蜜
在模板模式中使用挂钩(hook)
存在一个空实现的方法,我们称这种方法为hook。子类可以视情况来决定是否要覆盖它。
1>先对模板类Beverage进行修改
public abstract class Beverage {
/**
* 冲泡咖啡或茶的流程
*/
public final void create() {
boilWater();//把水煮沸
brew();//用沸水冲泡
pourInCup();//倒进杯子
addCoundiments();//加糖或其它
hook();//挂钩
}
//空实现方法
public void hook() {
}
public void boilWater() {
System.out.println("煮开水");
}
public abstract void brew();
public void pourInCup() {
System.out.println("倒进杯子");
}
public abstract void addCoundiments();
}
2>假设咖啡店搞活动,和一杯咖啡送一杯,修改咖啡(Coffee)类
public class Coffee extends Beverage {
/**
* @see com.study.templatepattern.Beverage#brew()
*/
@Override
public void brew() {
System.out.println("用水冲咖啡");
}
/**
* @see com.study.templatepattern.Beverage#addCoundiments()
*/
@Override
public void addCoundiments() {
System.out.println("添加糖和牛奶");
}
/**
* @see com.study.templatepattern.Beverage#hook()
*/
@Override
public void hook() {
System.out.println("再来一杯");
}
}
这样在运行结果中有“再来一杯”
也可以这样使用挂钩,让其决定里面的代码是否执行
1>我们对模板类(Beverage)进行修改
public abstract class Beverage {
/**
* 冲泡咖啡或茶的流程
*/
public final void create() {
boilWater();//把水煮沸
brew();//用沸水冲泡
pourInCup();//倒进杯子
if (hook()) {
addCoundiments();//加糖或其它
}
}
public boolean hook() {
return true;
}
public void boilWater() {
System.out.println("煮开水");
}
public abstract void brew();
public void pourInCup() {
System.out.println("倒进杯子");
}
public abstract void addCoundiments();
}
2>对Coffee类进行修改,让其不添加配料
public class Coffee extends Beverage {
/**
* @see com.study.templatepattern.Beverage#brew()
*/
@Override
public void brew() {
System.out.println("用水冲咖啡");
}
/**
* @see com.study.templatepattern.Beverage#addCoundiments()
*/
@Override
public void addCoundiments() {
System.out.println("添加糖和牛奶");
}
/**
* @see com.study.templatepattern.Beverage#hook()
*/
@Override
public boolean hook() {
return false;
}
}
这样在运行结果中没有添加配料。
关于模板模式
1.模板模式定义了算法的步骤,把这些步骤的实现延迟到子类
2.模板模式为我们提供了一个代码复用的技巧
3.模板抽象类中可以定义具体方法、抽象方法和钩子方法
4.为了防止子类改变模板中的算法,可以将模板方法声明为final
5.钩子是一种方法,它在抽象类中不做事,或只做默认的事,子类可以选择是否实现它