基本介绍
- 模板方法模式,又叫模板模式,在一个抽象类公开定义了执行它的方法的末班,它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。
- 简单说,模板方法模式定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构,就可以重定义该算法的某些特定步骤。
- 这种类型的设计模式属于行为型模式。
### 原理类图 ![在这里插入图片描述](https://img-blog.csdnimg.cn/2020100223294732.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0phdmFLb2JlQnJ5YW50,size_16,color_FFFFFF,t_70#pic_center) 说明(模板方法模式的角色及职责) 1. AbstractClass 抽象类,类中实现了模板方法,定义了算法的骨架,具体的子类需要去实现其他的抽象方法operation2,3,4 2. ConcreteClass实现抽象方法抽象方法operation2,3,4,以完成算法中特定子类的步骤。
模板方法模式类图实例:
模板方法模式代码实例:
SoyaMilk:作将公共的行为抽取到抽象类中方法实现,将具体多样的行为定义为抽象方法。
//抽象类,表示豆浆
public abstract class SoyaMilk {
//模板方法,make,模板方法可以做成final,不让子类去覆盖。
final void make() {
select();
addCondiments();
soak();
beat();
}
//选材料
void select() {
System.out.println("第一步:选择好的新鲜黄豆");
}
//添加不同的配料,抽象方法,子类具体实现
abstract void addCondiments();
//浸泡
void soak() {
System.out.println("第三步,黄豆和配料开始浸泡,需要3小时");
}
void beat() {
System.out.println("第四步,黄豆和配料放到豆浆机去打碎");
}
}
ReadBeanSoyaMilk 具体使用者
public class ReadBeanSoyaMilk extends SoyaMilk {
@Override
void addCondiments() {
System.out.println("加入上好的红豆");
}
}
PeanutSoyaMilk 具体使用者
public class PeanutSoyaMilk extends SoyaMilk {
@Override
void addCondiments() {
System.out.println("加入上好的花生");
}
}
测试用例
public class Client {
public static void main(String[] args) {
//制作红豆豆浆
System.out.println("----制作红豆豆浆-----");
ReadBeanSoyaMilk readBeanSoyaMilk = new ReadBeanSoyaMilk();
readBeanSoyaMilk.make();
System.out.println("----制作花生豆浆-----");
PeanutSoyaMilk peanutSoyaMilk = new PeanutSoyaMilk();
peanutSoyaMilk.make();
}
}
模板方法的钩子方法
在模板方法模式的父类中,可以定义一个默认方法,它不做任何事且子类可视情况选择是否覆盖它,该方法称为“钩子”。
代码实例
通过新增的customerWantCondiments()可以选择是否覆盖addCondiments()方法
//抽象类,表示豆浆
public abstract class SoyaMilk {
//模板方法,make,模板方法可以做成final,不让子类去覆盖。
final void make() {
select();
if (customerWantCondiments()) {
addCondiments();
}
soak();
beat();
}
//选材料
void select() {
System.out.println("第一步:选择好的新鲜黄豆");
}
//添加不同的配料,抽象方法,子类具体实现
abstract void addCondiments();
//浸泡
void soak() {
System.out.println("第三步,黄豆和配料开始浸泡,需要3小时");
}
void beat() {
System.out.println("第四步,黄豆和配料放到豆浆机去打碎");
}
//钩子方法,决定是否需要添加配料
boolean customerWantCondiments() {
return true;
}
}
当customerWantCondiments()方法返回false的时候,则不会执行addCondiments()的重写。
public class PureSoyaMilk extends SoyaMilk {
@Override
void addCondiments() {
//空实现
}
@Override
boolean customerWantCondiments() {
return false;
}
}
模板方法模式在Spring框架应用的源码分析
在AbstractApplicationContext抽象类中,提供了refresh()方法作为模板方法。
点击postProcessBeanFactory(),其内部也是一个空实现,即为了方便子类重写的钩子方法。
点击onRefresh(),是一个预留的空实现方法,是为了方便子类重写父类的方法,相当于模板方法中的“钩子”方法。