模板方法模式
将某些操作的流程在类的方法中定义好,而将这些操作的具体步骤中的逻辑延迟到子类中去实现,这样子类可以在不改变操作流程的情况下,修改具体步骤中的逻辑。
这里定义操作执行流程的方法就称为模板方法,所有的子类都共享该方法,子类的多样性可以通过定义具体步骤的逻辑展现出来。
在模板方法模式中,需要先定义一个抽象父类(AbstractClass),这个父类被称为抽象模板,该类中主要包含两类方法:
- 基本方法: 也称为基本操作,是需要子类实现的方法,在模板方法中被调用;
- 模板方法: 可以有一个或者多个,该方法中定义了一些操作的执行流程,实现对基本操作的调度,完成固定的逻辑,子类继承后直接使用。通常该方法不允许被重写,因此利用
final
关键字修饰。
模板方法模式的组成
抽象模板类
确定父类具有哪些方法,以及模板方法的执行流程设计
public abstract class AbstractClass{
// 基本方法1
protected abstract void doSomething();
// 基本方法2
protected abstract void doAnything();
// 模板方法1, 设计操作的执行流程
public void templateMethod1() {
this.doAnything();
this.doSomething();
}
// 模板方法2, 设计操作的执行流程
public void templateMethod2() {
this.doSomething();
this.doAnything();
}
}
具体模板类
子类根据具体的需求实现父类中的基本方法
public class ConcreteClass extends AbstractClass {
// 根据需求实现基本方法中的逻辑
protected abstract void doSomething() {
System.out.println("我是具体的实现,这是我的逻辑,我做点啥呢...");
}
// 根据需求实现基本方法中的逻辑
protected abstract void doAnything() {
System.out.println("我是具体的实现,这是我的逻辑,我想做啥就做啥...");
}
}
场景类
对模板方法的测试
public class Client {
public static void main(String[] args) {
AbstractClass myClass = new ConcreteClass();
// 调用模板方法
myClass.templateMethod1();
myClass.templateMethod1();
}
}
模板方法模式的优缺点
优点
- 提取了公共部分的代码,便于维护,子类只需要关心自己的特点不需要关心具体的行为,行为由父类同一控制
缺点
- 父类的执行结果由子类控制,代码的可阅读性难度增大
模板方法模式的使用场景
- 多个子类有公有的方法,且对方法的执行逻辑基本相同
- 重要、复杂的算法,可以把核心算法设计为模板方法,其它相关方法的细节由子类来实现
- 代码重构时,可以把相同的代码抽取到父类中