设计模式学习专栏八--------模板方法模式
名称 : 模板方法模式 (Template Method)
价值观念: 封装算法
场景
创建咖啡和茶
最初的设计
发现第一步和第三步是相同的步骤, 因此将它们抽取到 父类中
- 仔细观察 , 冲泡步骤的 第二和第四步实质上是一样的, 只是对于不同的饮料有不同的实现. 我们可以把 它们也进行抽象吗?
进一步设计
将泡步骤的 第二和第四步 也抽取出来
以下比较好理解,就直接截图过来了
我们做了什么
模板方法模式总览
定义:在一个方法中
(父类)定义一个算法的骨架
, 而将一些步骤延迟到子类中
. 模板方法使得子类 可以在不改变算法结构的情况下, 重新定义算法中的某些步骤
-
模式的理解
-
类图
-
角色
- 定义了算法步骤 的父类
- 提供某些步骤实现的子类
-
对模板方法进行挂钩(常见的钩子函数)
-
钩子是一种被声明在抽象类中的方法,但只有空的或者默认的实现 . 钩子的存在,可以让子类有能力对算法的不同点进行挂钩 . 要不要挂钩, 由子类决定
-
①钩子能够有机会对模板方法中即将发生(或者刚刚发生)的步骤做出反应
②钩子可以让子类实现算法中的可选部分
③钩子也可以让子类有能力为其抽象类做出一些决定 . 比如之前学的观察者模式中的setChanged()方法
-
使用场景 : 比如我们的各种 生命周期的钩子函数
-
-
案例代码部分
-
CaffeineBeverage
public abstract class CaffeineBeverage { final void prepareRecipe() { boilWater(); brew(); pourInCup(); addCondiments(); } abstract void brew(); abstract void addCondiments(); void boilWater() { System.out.println("Boiling water"); } void pourInCup() { System.out.println("Pouring into cup"); } } 复制代码
-
Tea
public class Tea extends CaffeineBeverage { public void brew() { System.out.println("Steeping the tea"); } public void addCondiments() { System.out.println("Adding Lemon"); } } 复制代码
-
Coffee
public class Coffee extends CaffeineBeverage { public void brew() { System.out.println("Dripping Coffee through filter"); } public void addCondiments() { System.out.println("Adding Sugar and Milk"); } } 复制代码
-
主程序
public class BeverageTestDrive { public static void main(String[] args) { Tea tea = new Tea(); Coffee coffee = new Coffee(); System.out.println("\nMaking tea..."); tea.prepareRecipe(); System.out.println("\nMaking coffee..."); coffee.prepareRecipe(); } } 复制代码
-
输出结果
Making tea... Boiling water Steeping the tea Pouring into cup Adding Lemon Making coffee... Boiling water Dripping Coffee through filter Pouring into cup Adding Sugar and Milk 复制代码
参考
书籍: HeadFirst设计模式
代码参考地址: 我就是那个地址