1、模板方法模式的概念
模板方法模式定义了一个算法的步骤,并允许子类别为一个或多个步骤提供其实践方式。让子类别在不改变算法架构的情况下,重新定义算法中的某些步骤。
2、模板方法模式的实现要素
准备一个抽象类,将部分逻辑以具体方法的形式实现,然后声明一些抽象方法交由子类实现剩余逻辑,用钩子方法给予子类更大的灵活性。最后将方法汇总构成一个不可改变的模板方法。
3、模板方法模式的实现步骤
第一步:构建抽象基类,为所有子类提供的一个算法框架
package com.bc.template;
/**
* 抽象基类,为所有子类提供的一个算法框架
*/
public abstract class RefreshBeverage {
/**
* 封装了所有子类共同遵循的算法框架
*/
public final void prepareBeverageTemplate() {
//步骤1 将水煮沸
boilWater();
//步骤2 泡茶饮料
brew();
//步骤3 将饮料倒入杯中
pourInCup();
if (isCustomerWantsCondiments()) {
//步骤4 加入调味料
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 Test {
public static void main(String[] args) {
System.out.println("制备咖啡...");
RefreshBeverage b1 = new Coffee();
b1.prepareBeverageTemplate();
System.out.println("咖啡好了!");
System.out.println("\n******************************************");
System.out.println("制备茶...");
RefreshBeverage b2 = new Tea();
b2.prepareBeverageTemplate();
System.out.println("茶好了!");
}
}
输出结果:
制备咖啡...
将水煮沸
用沸水冲泡咖啡
将饮料倒入杯中
加入糖和牛奶
咖啡好了!
******************************************
制备茶...
将水煮沸
用80度的热水浸泡茶叶5分钟
将饮料倒入杯中
茶好了!
4、模板方法模式的适用场景
1.算法或操作遵循相似的逻辑
2.重构时(把相同的代码抽取到父类中)
3.重要、复杂的算法,核心算法设计为模板算法
5、模板方法模式的优点和缺点
优点:
1.封装性好
2.复用性好
3.屏蔽性好
4.便于维护
缺点:
由于使用了继承方式,那么子类便不能再去继承其它类,不易于扩展