模板方法模式
准备一个抽象类,提供一个模板方法去实现顶级逻辑,这个抽象类可以实现一些通用的具体逻辑,同时声明一些抽象方法由子类去实现这些基本方法,再者这个抽象类可以提供一种hook机制,这种hook机制使得模板方法更加的灵活。
类型:
行为型模式(父类与子类之间的行为型模式)
模板方法的几个角色:
- AbstractTemplate:抽象模板,定义模板方法,同时暴露具体算法的抽象接口。
- ConcreteTemplate:具体模板,实现抽象模板暴露的抽象方法。
抽象模板中具有的3个角色:
- 模板方法
- 抽象方法
- hook()方法
模板方法关系图:
模板方法示例:
本人喜欢吃麻辣香锅,所以本例子麻辣香锅的制作过程来写,麻辣香锅的具体的制作过程一般有以下几个步骤:
- 挑选自己喜欢吃的食材
- 老板问你是否加辣
- 厨师制作麻辣香锅
- 装盘
- 自己动手加点免费的小菜。
抽象模板类:
/**
* Create by zhaihongwei on 2018/3/24
* 抽象模板
* 抽象麻辣香锅类
*/
public abstract class SpicyFragrantPot {
/**
* 麻辣香锅制作的方法
* 模板方法,声明为final,防止子类更改模板方法
*/
public final void makingMethod() {
// 选食材
choose();
// 根据客户需求判断是否执行加辣操作
if(isHotHook()) {
addHot();
}
// 制作并装盘
makeAndDish();
// 根据顾客喜好添加小菜,可以不加。
coleHook();
}
/**
* 挑选食材的方法
* 抽象方法,由子类实现
*/
public abstract void choose();
/**
* 询问顾客是否加辣
* hook方法的第一种作用,可以灵活的改变模板方法。
*/
public boolean isHotHook() {
return true;
}
/**
* 加辣的方法
* 具体方法,加辣的动作基本相同,由父类自己实现
*/
public void addHot() {
System.out.println("加了辣椒!!!");
}
/**
* 厨师制作并装盘方法
* 具体方法,装盘的动作基本是相同的,由父类自己实现。
*/
public void makeAndDish() {
System.out.println("装好盘啦!");
}
/**
* 根据顾客喜好,自己加小菜,也可以不加
* hook方法的第二种作用。
*/
public void coleHook() {
// 空实现,根据顾客,喜好自己实现
}
}
具体模板类—顾客A:
/**
* Create by zhaihongwei on 2018/3/24
* 具体的模板
* 顾客A
*/
public class CustomerA extends SpicyFragrantPot {
@Override
public void choose() {
System.out.println("顾客A挑选了balabala好多菜!!!");
}
@Override
public boolean isHotHook() {
System.out.println("顾客A需要加辣!!!");
return true;
}
@Override
public void coleHook() {
System.out.println("顾客A自己打了一碗汤,加了一点咸菜");
}
}
具体模板类—顾客B:
/**
* Create by zhaihongwei on 2018/3/24
* 具体的模板
* 顾客B
*/
public class CustomerB extends SpicyFragrantPot {
@Override
public void choose() {
System.out.println("顾客B挑选了balabala好多菜!!!");
}
@Override
public boolean isHotHook() {
System.out.println("顾客B不需要加辣!!!");
return false;
}
@Override
public void coleHook() {
System.out.println("顾客B只打了一碗汤!!!");
}
}
测试类:
/**
* Create by zhaihongwei on 2018/3/24
*/
public class TemplateTest {
public static void main(String[] args) {
SpicyFragrantPot spicyFragrantPotA = new CustomerA();
spicyFragrantPotA.makingMethod();
System.out.println("-----------------------------------");
SpicyFragrantPot spicyFragrantPotB = new CustomerB();
spicyFragrantPotB.makingMethod();
}
}
测试结果:
顾客A挑选了balabala好多菜!!!
顾客A需要加辣!!!
加了辣椒!!!
装好盘啦!
顾客A自己打了一碗汤,加了一点咸菜
-----------------------------------
顾客B挑选了balabala好多菜!!!
顾客B不需要加辣!!!
装好盘啦!
顾客B只打了一碗汤!!!
总结:
根据上面的例子,相信大家已经对模板方法有一定的认识了,下面将具体讲一下hook方法的作用。
hook方法的作用:
通过hook方法,子类根据需求决定是否重写hook方法。
- 可以通过hook方法改变模板方法中的具体实现步骤。如:isHotHook()方法。
- 也可给出一个空的hook方法,让子类去实现,这种方式并不改变模板方法的执行。如coleHook()方法。
模板方法模式的优缺点:
优点:
模板方法模式通过把通用的方法在超类中实现,避免子类中的重复编写代码。
由子类实现一些具体的方法,更加的灵活,易于算法扩展。
缺点:
如果算法较多,会产生大量的具体算法类。