行为型-模板方法模式
2026/1/15大约 2 分钟Java设计模式行为型模式模板方法模式Java设计模式面向对象架构设计最佳实践代码优化
概述
模板方法模式(Template Method Pattern)定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
适用场景
- 一次性实现一个算法的不变部分,并将可变的行为留给子类来实现
- 各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复
- 控制子类的扩展
角色组成
- AbstractClass(抽象类):定义抽象的原语操作,实现模板方法
- ConcreteClass(具体类):实现原语操作以完成算法中与特定子类相关的步骤
代码实现
1. 抽象类
public abstract class AbstractClass {
// 模板方法(final 防止子类重写)
public final void templateMethod() {
step1();
step2();
if (hook()) {
step3();
}
step4();
}
// 具体方法
private void step1() {
System.out.println("步骤1:通用操作");
}
// 抽象方法(子类必须实现)
protected abstract void step2();
protected abstract void step3();
// 具体方法
private void step4() {
System.out.println("步骤4:通用操作");
}
// 钩子方法(子类可选重写)
protected boolean hook() {
return true;
}
}2. 具体类
public class ConcreteClassA extends AbstractClass {
@Override
protected void step2() {
System.out.println("步骤2:ConcreteClassA 的实现");
}
@Override
protected void step3() {
System.out.println("步骤3:ConcreteClassA 的实现");
}
}
public class ConcreteClassB extends AbstractClass {
@Override
protected void step2() {
System.out.println("步骤2:ConcreteClassB 的实现");
}
@Override
protected void step3() {
System.out.println("步骤3:ConcreteClassB 的实现");
}
// 重写钩子方法,跳过步骤3
@Override
protected boolean hook() {
return false;
}
}3. 客户端
public class Client {
public static void main(String[] args) {
System.out.println("=== ConcreteClassA ===");
AbstractClass classA = new ConcreteClassA();
classA.templateMethod();
System.out.println("\n=== ConcreteClassB ===");
AbstractClass classB = new ConcreteClassB();
classB.templateMethod();
}
}# 输出
=== ConcreteClassA ===
步骤1:通用操作
步骤2:ConcreteClassA 的实现
步骤3:ConcreteClassA 的实现
步骤4:通用操作
=== ConcreteClassB ===
步骤1:通用操作
步骤2:ConcreteClassB 的实现
步骤4:通用操作类图
实际案例:JDBC 模板
public abstract class JdbcTemplate {
// 模板方法
public final Object execute(String sql) {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
conn = getConnection();
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
return handleResultSet(rs); // 抽象方法
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
close(rs, stmt, conn);
}
}
protected abstract Object handleResultSet(ResultSet rs) throws SQLException;
private Connection getConnection() throws SQLException {
// 获取连接
return null;
}
private void close(ResultSet rs, Statement stmt, Connection conn) {
// 关闭资源
}
}JDK 中的应用
java.io.InputStream#read()java.util.AbstractList#indexOf()javax.servlet.http.HttpServlet#service()
优缺点
优点:
- 封装不变部分,扩展可变部分
- 提取公共代码,便于维护
- 行为由父类控制,子类实现
缺点:
- 每一个不同的实现都需要一个子类
- 增加了系统复杂度
