模板方法模式
原理类图
对原理类图的是说明
- AbstractClass 抽象类,类中实现了模板方法(template),定义了算法的骨架,具体子类需要实现其他的抽象方法(operation2,3,4)
- ConcreteClass 实现抽象方法operation2,3,4,以完成算法中特定子类的步骤
案例
豆浆的制作
第一步:选好新鲜的黄豆.
第二步:添加不同的配料(红枣、花生等)
第三步:配料和黄豆开始浸泡,需要三小时
第四步:配料和黄豆放到豆浆机去打碎
/**
* Created by Chaolong on 2021/12/6.
*/
// 抽象类,表示豆浆
public abstract class SoyaMilk {
// 模板方法,make, 模板方法可以做成final,不让子类去覆盖
public final void make(){
select();
addCondiments();
soak();
beat();
}
// 选择材料
private void select() {
System.out.println("第一步:选好新鲜的黄豆");
}
// 添加不同的配料,抽象方法,子类具体去实现
abstract void addCondiments();
// 浸泡
private void soak(){
System.out.println("第三步:配料和黄豆开始浸泡,需要三小时");
}
// 打碎
private void beat() {
System.out.println("第四步:配料和黄豆放到豆浆机去打碎");
}
}
/**
* Created by Chaolong on 2021/12/6.
*/
public class RedBeanSoyaMilk extends SoyaMilk{
@Override
void addCondiments() {
System.out.println("加入上好的红豆");
}
}
/**
* Created by Chaolong on 2021/12/6.
*/
public class PeanutSoyaMile extends SoyaMilk{
@Override
void addCondiments() {
System.out.println("加入上好的花生");
}
}
/**
* Created by Chaolong on 2021/12/6.
*/
public class Client {
public static void main(String[] args) {
System.out.println("制作红豆豆浆==========");
SoyaMilk redBeanSoyaMilk = new RedBeanSoyaMilk();
redBeanSoyaMilk.make();
System.out.println("制作花生豆浆==========");
SoyaMilk peanutSoyaMile = new PeanutSoyaMile();
peanutSoyaMile.make();
}
}
模板中的钩子方法
在模板方法模式的父类中,我们可以定义一个方法,他默认不做任何事情,子类可以视情况要不要覆盖它,该方法成为钩子。
案例:
比如我们要做纯豆浆,不需要加入任何配料
/**
* Created by Chaolong on 2021/12/6.
*/
// 抽象类,表示豆浆
public abstract class SoyaMilk {
// 模板方法,make, 模板方法可以做成final,不让子类去覆盖
public final void make(){
select();
// 判断是否添加配料
if (this.customerWantCondiments()) {
addCondiments();
}
soak();
beat();
}
// 选择材料
private void select() {
System.out.println("第一步:选好新鲜的黄豆");
}
// 添加不同的配料,抽象方法,子类具体去实现
abstract void addCondiments();
// 浸泡
private void soak(){
System.out.println("第三步:配料和黄豆开始浸泡,需要三小时");
}
// 打碎
private void beat() {
System.out.println("第四步:配料和黄豆放到豆浆机去打碎");
}
// 钩子函数,决定是否需要添加配料
boolean customerWantCondiments(){
return true;
}
}
/**
* Created by Chaolong on 2021/12/6.
*/
public class PureSoyaMilk extends SoyaMilk {
@Override
void addCondiments() {
}
@Override
boolean customerWantCondiments() {
return false;
}
}