介绍
模板方法定义:
在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。
分析一下定义,由抽象类定义执行的方法(执行模板),这个方法中可能会有多个步骤,但是可能每个子类对于每个步骤有不同的实现方式,所以将这些步骤延迟至子类实现,但是最终执行这些方法的具体形式需要按照抽象类定义的模板执行。
不是特别难以理解,接下来以案例的方式来介绍
案例
假如我们现在要制作包子,这里简化一下步骤,制作包子总共需要3步,擀面,包馅,发面。其中擀面和发面是每一种包子制作都需要的,但是包馅则会根据不同种类的包子有不同的实现,假设我们需要制作肉包和菜包。
下面我们看看代码的具体实现
包子模板类
public abstract class SteamedBunTemplate {
public void roll(){
System.out.println("擀面完成");
}
public void leavenDough(){
System.out.println("发面完成完成");
}
//添加馅料接口,交给子类实现
public abstract void Filling();
//加final防止子类修改模板函数
public final void make()
{
roll();
leavenDough();
filling();
}
}
肉包子类
public class MeatBun extends SteamedBunTemplate{
//子类需要实现添加馅料方法
@Override
public void Filling() {
System.out.println("添加肉馅完成");
}
}
菜包子类
public class VegetableBun extends SteamedBunTemplate{
//子类需要实现添加馅料方法
@Override
public void filling() {
System.out.println("添加菜馅完成");
}
}
模板测试类
public class TemplateTest {
@Test
public void test()
{
MeatBun meatBun=new MeatBun();
meatBun.make();
VegetableBun vegetableBun=new VegetableBun();
vegetableBun.make();
}
}
测试结果类
擀面完成
发面完成完成
添加肉馅完成
擀面完成
发面完成完成
添加菜馅完成
模板添加钩子
添加钩子是什么意思呢,就是指可能有一些方法,只有一部分子类想在模板执行时调用,给子类提供一些开放的模板执行方法调整接口。
假设我们的案例中,我们有时候需要制作生煎包,也就是不发面而改为煎包子(其实我也不清楚生煎包是怎么做的,如果有误请见谅),那么我们就需要提供一个钩子方法,来操作模板执行。具体实现看代码
包子模板类
public abstract class SteamedBunTemplate {
public void roll(){
System.out.println("擀面完成");
}
public void leavenDough(){
System.out.println("发面完成");
}
public void fire(){
System.out.println("生煎包制作完成");
}
//添加馅料接口,交给子类实现
public abstract void filling();
//加final防止子类修改模板函数
public final void make()
{
roll();
if(!makeFriedBuns()){
leavenDough();
}
filling();
if(makeFriedBuns()){
fire();
}
}
//钩子方法,默认是制作普通包子
public boolean makeFriedBuns()
{
return false;
}
}
肉包子类
public class MeatBun extends SteamedBunTemplate{
//子类需要实现添加馅料方法
@Override
public void filling() {
System.out.println("添加肉馅完成");
}
//子类重写钩子方法,返回true,表示制作生煎包
@Override
public boolean makeFriedBuns() {
return true;
}
}
测试
@Test
public void test()
{
MeatBun meatBun=new MeatBun();
meatBun.make();
VegetableBun vegetableBun=new VegetableBun();
vegetableBun.make();
}
测试结果
擀面完成
添加肉馅完成
生煎包制作完成
擀面完成
发面完成
添加菜馅完成
总结
模板模式适用于一部分业务过程有着相同或者相近的执行逻辑步骤时进行处理,其统一了业务的算法结构的同时也给算法执行本身提供了较强的灵活性。
缺点是每一个相近的业务都需要实现一个自己的子类,容易导致类数量过多。