Java模板方法模式
模板方法模式定义算法骨架,子类实现具体步骤。
模式定义
意图:定义算法骨架,将某些步骤延迟到子类实现。
适用场景
- 多个类有相似算法结构
- 算法固定,某些步骤可变
- 控制子类扩展点
模式结构
抽象模板类
Java
public abstract class AbstractTemplate {
// 模板方法(定义算法骨架,final防止覆写)
public final void execute() {
step1();
step2();
step3();
hook(); // 钩子方法
}
// 基本方法(抽象,子类实现)
protected abstract void step1();
protected abstract void step2();
// 基本方法(可覆写)
protected void step3() {
System.out.println("默认步骤3");
}
// 钩子方法(可选扩展)
protected void hook() {
// 默认空实现,子类可选择性覆写
}
}
具体实现类
Java
public class ConcreteA extends AbstractTemplate {
@Override
protected void step1() {
System.out.println("ConcreteA - 步骤1");
}
@Override
protected void step2() {
System.out.println("ConcreteA - 步骤2");
}
@Override
protected void step3() {
System.out.println("ConcreteA - 步骤3(覆写)");
}
}
public class ConcreteB extends AbstractTemplate {
@Override
protected void step1() {
System.out.println("ConcreteB - 步骤1");
}
@Override
protected void step2() {
System.out.println("ConcreteB - 步骤2");
}
@Override
protected void hook() {
System.out.println("ConcreteB - 钩子方法");
}
}
使用示例
Java
AbstractTemplate templateA = new ConcreteA();
templateA.execute();
// ConcreteA - 步骤1
// ConcreteA - 步骤2
// ConcreteA - 步骤3(覆写)
AbstractTemplate templateB = new ConcreteB();
templateB.execute();
// ConcreteB - 步骤1
// ConcreteB - 步骤2
// 默认步骤3
// ConcreteB - 钩子方法
实际应用示例
数据处理模板
Java
public abstract class DataProcessor {
public final void process() {
loadData();
validateData();
transformData();
saveData();
}
protected abstract void loadData();
protected void validateData() {
System.out.println("默认验证");
}
protected abstract void transformData();
protected abstract void saveData();
}
public class CsvProcessor extends DataProcessor {
@Override
protected void loadData() {
System.out.println("加载CSV数据");
}
@Override
protected void transformData() {
System.out.println("转换CSV数据");
}
@Override
protected void saveData() {
System.out.println("保存CSV数据");
}
}
public class JsonProcessor extends DataProcessor {
@Override
protected void loadData() {
System.out.println("加载JSON数据");
}
@Override
protected void validateData() {
System.out.println("JSON格式验证");
}
@Override
protected void transformData() {
System.out.println("转换JSON数据");
}
@Override
protected void saveData() {
System.out.println("保存JSON数据");
}
}
HttpServlet模板
Java Servlet的HttpServlet就是模板方法模式:
Java
public class HttpServlet {
// 模板方法
public void service(HttpServletRequest req, HttpServletResponse resp) {
String method = req.getMethod();
if ("GET".equals(method)) {
doGet(req, resp); // 子类实现
} else if ("POST".equals(method)) {
doPost(req, resp); // 子类实现
}
// ...
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
// 默认405响应
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
// 默认405响应
}
}
// 自定义Servlet覆写doGet、doPost
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
// 处理GET请求
}
}
钩子方法
钩子方法允许子类控制模板流程:
Java
public abstract class Game {
public final void play() {
initialize();
if (isPlayable()) { // 钩子方法控制流程
startPlay();
endPlay();
}
}
protected abstract void initialize();
protected abstract void startPlay();
protected abstract void endPlay();
// 钩子方法:是否可玩
protected boolean isPlayable() {
return true; // 默认可玩
}
}
public class Chess extends Game {
@Override
protected boolean isPlayable() {
return false; // 不能玩
}
// 其他方法...
}
模板方法类型
| 类型 | 特点 | 使用方式 |
|---|---|---|
| 抽象方法 | 子类必须实现 | abstract修饰 |
| 具体方法 | 子类可覆写 | protected修饰 |
| 钩子方法 | 子类可选覆写 | 空实现 |
| final方法 | 子类不能覆写 | final修饰 |
模板方法模式优点
- 代码复用,公共逻辑在父类
- 控制子类扩展点
- 统一算法结构
注意事项
模板方法应声明为final防止覆写
基本方法用protected,限制外部调用
钩子方法提供扩展灵活性
避免模板方法过长,影响阅读
要点总结
- 模板方法模式定义算法骨架,子类实现细节
- 抽象类定义模板方法(final)和基本方法
- 子类覆写抽象方法,可选覆写钩子方法
- HttpServlet的service()是模板方法的应用
- 适用于固定流程、可变步骤的场景
📝 发现内容有误?点击此处直接编辑