在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。
应用场景
1、有多个子类共有的方法,且逻辑相同。
2、重要的、复杂的方法,可以考虑作为模板方法。
模式结构
1、抽象模板(Abstract Template):抽象模板是一个抽象类。抽象模板定义了若干个方法以表示算法的各个步骤,这些方法中有抽象方法也有非抽象方法,其中的抽象方法称为原语操作(Primitive Operation)。重要的一点是,抽象模板中还定义了一个称之为模板方法的方法,该方法不仅包含有抽象模板中表示算法步骤的方法调用,而且也可以包含有定义在抽象模板中的其他对象的方法调用,即模板方法定义了算法的骨架。
注意:一般模板方法都加上 final 关键词。
2、具体模板(Concrete Template):具体模板是抽象模板的子类,实现抽象模板中的原语操作。
下图中,描述了一个做饭的场景,cook() 方法为模板方法,cooking() 方法和 complete() 方法用于给子类重写。
代码案例
上图中做饭的场景,首先,有一个抽象方法:
public abstract class CookTemplate {
public final void cook() {
prepare();
cooking();
complete();
}
/**
* 准备工作
* */
private void prepare() {
System.out.println("准备好油盐酱醋。");
}
/**
* 开始烹饪
* */
abstract void cooking();
/**
* 烹饪完成
* */
abstract void complete();
}
创建两个子类:
public class BouilliTemplate extends CookTemplate {
@Override
void cooking() {
System.out.println("开始烧红烧肉。");
}
@Override
void complete() {
System.out.println("完成了红烧肉。");
}
}
public class SoupTemplate extends CookTemplate {
@Override
void cooking() {
System.out.println("开始烧汤。");
}
@Override
void complete() {
System.out.println("汤烧好了。");
}
}
创建测试类
public class CookTemplateTest {
public static void main(String[] args) {
CookTemplate cook = new BouilliTemplate();
cook.cook();
System.out.println("---");
CookTemplate cook2 = new SoupTemplate();
cook2.cook();
}
}
优点
1、封装不变部分,扩展可变部分。
2、提取公共代码,便于维护。
3、具体模板实现细节不会改变整个算法的框架。
缺点
每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。