概述
模板模式(Template Pattern),一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。
是基于继承的代码复用的基本技术。一个抽象类中,有一个主方法,再定义1…n个方法,可以是抽象的,也可以是实际的方法,继承该抽象类,重写抽象方法,通过调用抽象类,实现对子类的调用。
涉及角色
- AbstractClass
抽象类:定义抽象操作,以便让子类实现,是一个顶级逻辑的组成部分;定义并实现了一个模板方法,是一个顶级逻辑的框架 - ConcreteClass
具体类:实现父类所定义的抽象方法
UML
使用场景
- 有多个子类共有的方法,且逻辑相同
- 复杂的方法,可以考虑作为模板方法,对其行分割
优点
- 封装不变部分,扩展可变部分,子类实现算法的某些细节,有助于算法的扩展
- 提取公共代码,实现了代码复用,便于维护
- 行为由父类控制,子类实现
缺点
- 每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大,需要花更多的时间去理清类之间的关系
代码示例
比如观看DVD:流程是打开总电源、打开电视电源、操作dvd…… ,比如其中操作dvd根据习惯有的不使用遥控器直接操作DVD,也有人习惯使用遥控器操作DVD,这部分需要因人而异,但都必须操作。
抽象类
package com.designpattern.template;
public abstract class AbstractTemplate {
//模板方法
public void playDVD(){
//调用基本方法
openPower();
openTV();
operateDVD();
}
//基本方法的声明(由子类实现)
protected abstract void operateDVD();
//基本方法(已经实现)
private final void openPower(){
System.err.println("打开总电源……");
}
protected void openTV(){
System.err.println("使用遥控器打开TV开关……");
}
}
具体类,实现了父类所声明的基本方法,abstract 方法所代表的就是强制子类实现的剩余逻辑
package com.designpattern.template;
public class ConcreteTemplate extends AbstractTemplate{
@Override
protected void operateDVD() {
// TODO Auto-generated method stub
System.err.println("\t操作DVD:直接打开dvd电源");
System.err.println("\t操作DVD:使用遥控器打开光盘仓");
System.err.println("\t操作DVD:放入光盘");
System.err.println("\t操作DVD:直接关闭光盘仓");
}
}
package com.designpattern.template;
public class TestMain {
public static void main(String[] args) {
ConcreteTemplate concreteTemplate = new ConcreteTemplate();
concreteTemplate.playDVD();
}
}
打开总电源……
使用遥控器打开TV开关……
操作DVD:直接打开dvd电源
操作DVD:使用遥控器打开光盘仓
操作DVD:放入光盘
操作DVD:直接关闭光盘仓