22.设计模式-TEMPLATE METHOD(模板方法)
一、模式定义与核心思想
模板方法模式是一种行为型设计模式,其核心目标是定义算法的骨架,将某些步骤延迟到子类中实现。该模式通过将不变逻辑与可变逻辑解耦,实现以下核心价值:
- 算法复用:在抽象类中固化公共流程,减少重复代码(如Spring框架的
JdbcTemplate
统一处理数据库连接)。 - 扩展可控:子类仅重写特定步骤,避免破坏整体结构(如游戏角色状态机中不同行为的差异化实现)。
- 反向控制:父类控制流程调用顺序,子类专注具体实现(如Android Activity生命周期管理)。
核心设计哲学:
- 封装不变:公共步骤(如资源初始化、异常处理)在抽象类中实现,消除冗余。
- 开放变化:通过抽象方法或钩子方法(Hook Method)暴露扩展点,支持灵活定制。
典型应用场景:
- 框架设计(如Spring Boot自动配置流程)
- 多平台功能适配(如跨系统安装器统一流程)
- 业务流程标准化(如电商订单状态流转)
二、模式组成与UML类图
核心角色
- AbstractClass(抽象类):
-
- 定义模板方法
templateMethod()
,编排算法步骤(如prepareRecipe()
定义饮料制作流程)。 - 包含具体方法(如
boilWater()
)和抽象方法(如brew()
)。
- 定义模板方法
- ConcreteClass(具体类):
-
- 实现抽象方法,提供差异化逻辑(如
Coffee
和Tea
重写冲泡步骤)。 - 可选覆盖钩子方法实现流程微调(如跳过某些步骤)。
- 实现抽象方法,提供差异化逻辑(如
UML类图
classDiagram
class AbstractClass {
<<abstract>>
+templateMethod()
#step1()
#step2()
+concreteStep()
}
class ConcreteClassA {
+step1()
+step2()
}
class ConcreteClassB {
+step1()
+step2()
}
AbstractClass <|-- ConcreteClassA
AbstractClass <|-- ConcreteClassB
三、代码实现示例
场景:实现跨平台文件处理框架(文本文件与二进制文件差异化解析)
1. 抽象类定义模板方法
public abstract class FileProcessor {
// 模板方法(final防止子类重写流程)
public final void processFile(String filename) {
openFile(filename);
readData();
closeFile();
}
// 抽象方法(由子类实现)
protected abstract void openFile(String filename);
protected abstract void readData();
// 具体方法(公共逻辑)
private void closeFile() {
System.out.println("关闭文件句柄");
}
}
2. 具体类实现差异化逻辑
// 文本文件处理器
public class TextFileProcessor extends FileProcessor {
@Override
protected void openFile(String filename) {
System.out.println("以文本模式打开文件: " + filename);
}
@Override
protected void readData() {
System.out.println("逐行读取文本内容...");
}
}
// 二进制文件处理器
public class BinaryFileProcessor extends FileProcessor {
@Override
protected void openFile(String filename) {
System.out.println("以二进制模式打开文件: " + filename);
}
@Override
protected void readData() {
System.out.println("按字节流读取二进制数据...");
}
}
3. 客户端调用
public class Client {
public static void main(String[] args) {
FileProcessor textProcessor = new TextFileProcessor();
textProcessor.processFile("demo.txt");
FileProcessor binaryProcessor = new BinaryFileProcessor();
binaryProcessor.processFile("data.bin");
}
}
四、工业级源码应用
- Spring框架的JdbcTemplate
-
JdbcTemplate.execute()
方法定义SQL执行流程(获取连接、创建语句、执行、释放资源),具体SQL逻辑由回调接口实现。
public class JdbcTemplate {
public <T> T execute(ConnectionCallback<T> action) {
Connection con = getConnection();
try {
return action.doInConnection(con);
} finally {
releaseConnection(con);
}
}
}
- Android Activity生命周期
-
Activity.onCreate()
/onPause()
等方法为模板方法,子类重写特定生命周期回调。
- Java AQS同步器
-
AbstractQueuedSynchronizer
定义获取锁的模板方法acquire()
,子类实现tryAcquire()
等抽象方法。
- Spring Boot自动配置
-
@EnableAutoConfiguration
通过AutoConfigurationImportSelector
加载配置类,模板方法模式筛选符合条件的配置。
- 游戏引擎状态机
-
- Unity的角色行为状态机使用模板方法定义
Enter()
/Update()
/Exit()
流程,子类实现具体状态逻辑。
- Unity的角色行为状态机使用模板方法定义
五、模式优劣与最佳实践
优势:
- 代码复用率提升30%+:公共流程集中维护(如JDBC资源管理)。
- 符合开闭原则:新增功能通过扩展而非修改实现(如新增文件处理器类型)。
局限性:
- 类膨胀风险:每个差异化实现需单独子类(可通过组合模式优化)。
- 继承强耦合:子类与父类绑定,影响单元测试(推荐结合依赖注入)。
最佳实践:
- 钩子方法扩展:在模板方法中插入空方法(如
beforeRead()
),允许子类选择性覆盖。 - 与策略模式结合:将可变步骤委托给策略接口,减少子类数量。
- 异步流程支持:模板方法中集成CompletableFuture实现非阻塞调用(如高并发文件处理)。
总结
模板方法模式如同软件架构的“标准化流水线”,通过流程固化与局部定制的巧妙平衡,在框架设计、跨平台适配等领域展现出强大的生命力。其设计精髓在于将稳定性与灵活性统一,开发者需重点把控抽象方法的粒度,结合具体场景选择继承或组合策略,从而构建出高复用、易维护的现代化系统架构。