一、定义
在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤.
二、核心思想
1、这个模式是用来创建一个算法的模板
2、模板方法将算法定义成一组步骤,其中的任何步骤都可以是抽象的,由子类负责实现
3、确保算法的结构保持不变,同时由子类提供部分实现
三、相关设计原则
好莱坞原则
1、别调用(打电话给)我们,我们会调用(打电话给)你
2、用于防止依赖腐败
3、要不要用你,高层组件说了算
4、好莱坞原则让底层组件被挂钩进计算中,而又不会让高层组件依赖底层组件
钩子
1、钩子是一种被声明在抽象类中的方法,但只有空的或者默认的实现。钩子的存在可以让子类有能力对算法的不同点进行钩挂
2、有了钩子,我们可以让模板方法中的程序决定是否调用模板方法中的某些方法
四、使用场景
1、茶和咖啡的冲泡方式
茶:(1)把谁煮沸(2)用沸水冲泡咖啡(3)把咖啡倒进杯子(4)加糖和牛奶
咖啡:(1)把谁煮沸(2)用沸水浸泡茶叶(3)把茶倒进杯子(4)加柠檬
2、观察场景
两种冲泡方式有相同的地方,也有不同的地方
五、代码实现
package com.fengshu.limanman;
/**
*
* 1、理解模板方法 2、理解好莱坞原则 3、理解钩子的用法
*
* @author 李慢慢
*
*/
public class Temple {
public static void main(String[] args) {
CaffeineBeverage caffeineBeverage = new Coffee();
caffeineBeverage.pripareRecipe();
}
}
/**
* 制作咖啡因饮料的模板方法
*
*/
abstract class CaffeineBeverage {
/**
* final 确保算法的结构保持不变,也体现了好莱坞设计原则,让子类没办法直接调用父类(高层组件方法),只能由高层组件来调用子类实现的方法
*/
final void pripareRecipe() {
boilWater();
brew();
pourInCup();
// 钩子决定子类是否执行模板中的某些方法
if (needCondiments()) {
addCondiments();
}
}
/**
* 模板方法将算法定义成一组步骤,其中的任何步骤都可以是抽象的,由子类负责实现
*/
abstract void brew();
/**
* 模板方法将一部分的实现延迟到了子类中
*/
abstract void addCondiments();
void boilWater() {
System.out.println("Boiling water");
}
void pourInCup() {
System.out.println("Pouring into cup");
}
/**
* 使用了钩子默认true,由子类决定是否进行覆盖
*
* @return
*/
boolean needCondiments() {
return true;
}
}
class Coffee extends CaffeineBeverage {
/**
* 模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤
*
*/
@Override
void boilWater() {
System.out.println("Boiling water long long");
}
@Override
void brew() {
System.out.println("Dripping coffee through filter");
}
@Override
void addCondiments() {
System.out.println("Adding Sugar and Milk");
}
/**
* 有了钩子,我能够决定要不要覆盖方法。如果我不提供在自己 的方法,抽象类会提供一个默认的实现
*/
@Override
boolean needCondiments() {
return false;
}
}
class Tea extends CaffeineBeverage {
@Override
void brew() {
System.out.println("steeping the tea");
}
@Override
void addCondiments() {
System.out.println("Adding lemon");
}
}
六、参考
《Head First 设计模式》