一、模板设计模式的核心思想
模板设计模式(Template Method Pattern)的核心是 定义一个算法的骨架,将某些步骤延迟到子类中实现,使得子类可以在不改变算法整体结构的情况下,重新定义某些步骤的具体逻辑。
核心要点:
- 固定流程:父类定义算法的主要步骤(如“烧水→冲泡→倒入杯子→加调料”)。
- 可变细节:子类实现具体的步骤(如“如何冲泡茶叶”或“加什么调料”)。
- 控制反转:父类控制流程,子类填充细节。
二、Java 实现模板模式的步骤
1. 定义抽象类(模板类)
- 模板方法:用
final 修饰,定义算法的流程(防止子类覆盖流程)。
- 抽象方法:用
abstract 修饰,表示必须由子类实现的方法。
- 具体方法:父类提供默认实现的方法(如公共步骤)。
- 钩子方法(可选):提供默认逻辑的方法,子类可选择性覆盖(用于控制流程分支)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| public abstract class AbstractClass { public final void templateMethod() { step1(); step2(); step3(); if (hookMethod()) { step4(); } }
protected abstract void step2();
private void step1() { System.out.println("执行步骤1"); }
protected boolean hookMethod() { return true; }
private void step3() { System.out.println("执行步骤3"); }
protected abstract void step4(); }
|
2. 定义具体子类
子类继承抽象类,并实现其抽象方法。可以覆盖钩子方法以改变流程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| public class ConcreteClassA extends AbstractClass { @Override protected void step2() { System.out.println("ConcreteClassA 实现的步骤2"); }
@Override protected void step4() { System.out.println("ConcreteClassA 实现的步骤4"); }
@Override protected boolean hookMethod() { return false; } }
public class ConcreteClassB extends AbstractClass { @Override protected void step2() { System.out.println("ConcreteClassB 实现的步骤2"); }
@Override protected void step4() { System.out.println("ConcreteClassB 实现的步骤4"); } }
|
3. 使用模板模式
通过调用模板方法触发算法流程:
1 2 3 4 5 6 7 8 9
| public class Client { public static void main(String[] args) { AbstractClass instanceA = new ConcreteClassA(); instanceA.templateMethod();
AbstractClass instanceB = new ConcreteClassB(); instanceB.templateMethod(); } }
|
输出结果:
1 2 3 4 5 6 7 8
| 执行步骤1 ConcreteClassA 实现的步骤2 执行步骤3
执行步骤1 ConcreteClassB 实现的步骤2 执行步骤3 ConcreteClassB 实现的步骤4
|
三、Java 实现的关键细节
1. final 关键字的作用
- 模板方法必须用
final 修饰:防止子类覆盖算法的整体流程。
- 示例:
public final void templateMethod() { ... }
2. 抽象方法与具体方法
- 抽象方法:由子类实现差异化逻辑(如
step2() 和 step4())。
- 具体方法:父类提供公共逻辑(如
step1() 和 step3())。
3. 钩子方法(Hook Method)
- 用途:允许子类影响模板方法的流程(如控制是否执行某一步骤)。
- 实现:在父类中提供默认实现,子类可选择覆盖。
- 示例:
protected boolean hookMethod() { return true; }