模板方法模式定义了一个算法的骨架,将某些步骤推迟到子类中实现。模板方法定义一个算法的骨架,将一些步骤的实现延迟到子类中完成。这样做的目的是确保算法的结构保持不变,同时又可以为不同的子类提供特定步骤的实现。
比如去餐馆吃饭,餐馆有固定的流程(下单->上菜->吃饭->付款),这就是模板方法。但对于不同的顾客,他们点的菜不同(重写了上菜这一步骤)。
// 抽象类 - 模板方法
abstract class EmployeeApprover {
// 模板方法
public final void processRequest(EmployeeRequest request) {
collectEmployeeInfo(request); // 1
verifyEmployeeInfo(request); // 2
if (approveEmployee(request)) { // 3
hireEmployee(request); // 4
} else {
rejectEmployee(request); // 4
}
}
// 收集员工信息 - 由子类实现
protected abstract void collectEmployeeInfo(EmployeeRequest request);
// 验证员工资格 - 由子类实现
protected abstract void verifyEmployeeInfo(EmployeeRequest request);
// 核心决策 - 由子类实现
protected abstract boolean approveEmployee(EmployeeRequest request);
// 具体雇佣步骤
private void hireEmployee(EmployeeRequest request) {
System.out.println("已雇佣员工: " + request.getName());
}
// 具体拒绝步骤
private void rejectEmployee(EmployeeRequest request) {
System.out.println("已拒绝员工: " + request.getName());
}
}
// 具体子类 - 实现抽象方法
class ITEmployeeApprover extends EmployeeApprover {
@Override
protected void collectEmployeeInfo(EmployeeRequest request) {
// 收集IT员工信息
}
@Override
protected void verifyEmployeeInfo(EmployeeRequest request) {
// 验证IT员工资格
}
@Override
protected boolean approveEmployee(EmployeeRequest request) {
// 审核IT员工是否合格
return true;
}
}
// 抽象类 - 模板方法
abstract class OrderProcessor {
// 模板方法
public final void processOrder(Order order) {
collectOrderInfo(order); // 1
verifyOrderInfo(order); // 2
if (approveOrder(order)) { // 3
shipOrder(order); // 4
} else {
rejectOrder(order); // 4
}
}
// 收集订单信息 - 由子类实现
protected abstract void collectOrderInfo(Order order);
// 验证订单信息 - 由子类实现
protected abstract void verifyOrderInfo(Order order);
// 核心决策 - 由子类实现
protected abstract boolean approveOrder(Order order);
// 具体发货步骤
private void shipOrder(Order order) {
System.out.println("已发货订单: " + order.getId());
}
// 具体拒绝步骤
private void rejectOrder(Order order) {
System.out.println("已拒绝订单: " + order.getId());
}
}
// 具体子类 - 实现抽象方法
class OnlineOrderProcessor extends OrderProcessor {
@Override
protected void collectOrderInfo(Order order) {
// 收集在线订单信息
}
@Override
protected void verifyOrderInfo(Order order) {
// 验证在线订单信息
}
@Override
protected boolean approveOrder(Order order) {
// 审核在线订单是否合格
return true;
}
}
InputStream抽象类InputStream定义了读取数据的标准方法read(),而具体的读取方式由子类实现。
public abstract class InputStream implements Closeable {
public abstract int read() throws IOException;
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
public int read(byte b[], int off, int len) throws IOException {
// 模板方法
}
// 其他方法...
}
AbstractList抽象类AbstractList提供了模板方法addAll()用于批量添加元素,而具体的添加逻辑由子类实现。
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
public boolean addAll(Collection<? extends E> c) {
// 模板方法
return batchOperation(c, true);
}
private boolean batchOperation(...) {
// ...
for (E e : c)
result = add(e); // 调用抽象方法
}
public abstract boolean add(E e); // 抽象方法,子类实现
}
Spring JdbcTemplateJdbcTemplate使用模板方法模式对底层的JDBC操作进行封装,开发者只需实现回调接口即可。以query方法为例:
public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
public <T> T query(String sql, Object[] args, ResultSetExtractor<T> rse) throws DataAccessException {
// 模板方法
return query(sql, newArgPreparedStatementSetter(args), rse);
}
// 实际的查询逻辑
private <T> T query(PreparedStatementCreator psc, ResultSetExtractor<T> rse) throws DataAccessException {
// 具体的数据库操作...
rse.extractData(rs); // 调用回调接口
}
}
优点:
缺点:
使用经验:
模板方法模式是一种典型的通过交换算法步骤扩展功能的设计模式,适用于算法骨架固定,某些步骤需要不同实现的场景。恰当使用可以提高代码复用性和系统扩展性。