模板方法模式
模板方法模式用于在父类中定义流程骨架,把部分可变步骤交给子类实现。
一句话理解:流程固定,步骤可变。
解决什么问题
很多业务流程结构相同,但局部步骤不同。
例如文件导入:
text
读取文件
校验格式
解析数据
保存数据
记录日志Excel、CSV、JSON 的流程类似,但解析方式不同。模板方法可以把固定流程放在父类,把变化步骤留给子类。
基本结构
text
AbstractClass
-> templateMethod()
-> step1()
-> abstract step2()
-> hook()
ConcreteClass
-> implement step2()模板方法通常是 final,避免子类破坏流程顺序。
Java 示例
抽象导入流程:
java
abstract class DataImporter {
public final void importData(String filePath) {
String raw = read(filePath);
validate(raw);
Object data = parse(raw);
save(data);
afterImport(data);
}
protected String read(String filePath) {
System.out.println("read file: " + filePath);
return "file content";
}
protected void validate(String raw) {
if (raw == null || raw.trim().isEmpty()) {
throw new IllegalArgumentException("file is empty");
}
}
protected abstract Object parse(String raw);
protected void save(Object data) {
System.out.println("save data: " + data);
}
protected void afterImport(Object data) {
// hook method
}
}Excel 导入:
java
class ExcelDataImporter extends DataImporter {
protected Object parse(String raw) {
System.out.println("parse excel");
return "excel data";
}
protected void afterImport(Object data) {
System.out.println("send excel import message");
}
}CSV 导入:
java
class CsvDataImporter extends DataImporter {
protected Object parse(String raw) {
System.out.println("parse csv");
return "csv data";
}
}使用:
java
DataImporter importer = new ExcelDataImporter();
importer.importData("/tmp/order.xlsx");钩子方法
钩子方法是父类提供的可选扩展点。
java
protected void afterImport(Object data) {
// 默认不做事,子类需要时重写
}它可以让子类在不破坏主流程的情况下参与扩展。
使用场景
- 固定流程的业务处理。
- 文件导入导出。
- 支付流程。
- 数据同步。
- 框架生命周期方法。
- 测试框架的 setup/execute/teardown。
优点
- 复用固定流程。
- 子类只关心变化步骤。
- 流程顺序由父类控制,不容易被破坏。
- 适合框架设计。
缺点
- 依赖继承,灵活性不如组合。
- 子类过多时维护成本上升。
- 父类变化可能影响所有子类。
和策略模式的区别
| 模式 | 重点 |
|---|---|
| 模板方法 | 父类固定流程,子类改步骤 |
| 策略 | 通过组合替换整个算法 |
模板方法依赖继承,策略依赖组合。现代业务代码中,如果不需要强制流程骨架,策略通常更灵活。
实战注意
模板方法适合稳定流程。如果流程本身经常变,硬放到父类会导致父类越来越复杂。