需求:豆浆制作问题
编写制作豆浆的程序,说明如下:
- 制作豆浆的流程 选材–>添加配料–>浸泡–>放到豆浆机打碎
- 通过添加不同的配料,可以制作出不同口味的豆浆。
- 选材、浸泡、放到豆浆机这几个步骤对于每一种豆浆都一样。
1.模板方法模式基本介绍
- 在一个抽象类中公开定义了执行它的方法的模板,它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方法进行。
- 简单说,模板方法模式定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构,就可以重定义该算法的某些特定步骤。
- 属于行为型模式
2.类图
AbstractClass 抽象类,公开定义了模板方法
template()模板方法:在template()中规定了算法的大致流程,即方法的调用顺序之类。
ConcreteClass 按需要重写父类中的方法
3.模板方法模式解决豆浆制作问题
除了add()方法每个具体实现类不同,别的都相同,所以将add()做成抽象方法。
public abstract class SoyaMilk {
//模板方法不允许重写
public final void make(){
select();
add();
soak();
beat();
}
private void select(){
System.out.println("第一步,选择黄豆");
}
protected abstract void add();
private void soak(){
System.out.println("第三步,浸泡材料");
}
private void beat(){
System.out.println("第四步,打碎");
}
}
public class RedBeanSoyaMilk extends SoyaMilk {
protected void add() {
System.out.println("第二步,加入红豆");
}
}
public class PeanutSoyaMilk extends SoyaMilk {
protected void add() {
System.out.println("第二步,加入花生");
}
}
在Client端调用
public class Client {
public static void main(String[] args) {
System.out.println("---制作红豆豆浆---");
SoyaMilk redBeanSoyaMilk = new RedBeanSoyaMilk();
redBeanSoyaMilk.make();
System.out.println("---制作花生豆浆---");
SoyaMilk peanutSoyaMilk = new PeanutSoyaMilk();
peanutSoyaMilk.make();
}
}
4.模板方法模式的钩子方法
在模板方法模式的父类中,我们可以定义一个方法,它默认不做任何事情,子类可以视情况要不要覆盖它,该方法称为“钩子”
假如需要纯豆浆(不需要任何配料),使用钩子方法改造。
在SoyaMilk类中,添加新的方法:
//钩子方法
boolean customWantCondiments() {
return true;
}
在调用add()方法时,执行一次判断。
if (customWantCondiments()) {
add();
}
纯豆浆中需要重写customWantCondiments方法,即可不执行add()方法。
public class PureSoyaMilk extends SoyaMilk {
protected void add() {
}
@Override
boolean customWantCondiments() {
return false;
}
}
5.模板方法模式 SpringIOC容器初始化
AbstractApplicationContext是一个抽象类,其中的refresh()方法就是一个模板方法。