目录

模板方法模式 (Template Method Pattern)

定义算法骨架,将某些步骤延迟到子类实现

概述

模板方法模式是一种行为型设计模式,它在超类中定义一个算法的框架,允许子类在不修改结构的情况下重写算法的特定步骤。

适用场景

  • 多个类有相同的算法结构
  • 需要控制子类扩展
  • 代码复用,避免重复

基础实现

// 抽象类:定义模板
public abstract class DataImporter {
    
    // 模板方法(final 防止重写)
    public final void importData(String filePath) {
        validateFile(filePath);
        List<Data> dataList = parseFile(filePath);
        validateData(dataList);
        saveData(dataList);
        if (shouldNotify()) {
            sendNotification(dataList.size());
        }
    }
    
    private void validateFile(String filePath) {
        System.out.println("验证文件: " + filePath);
    }
    
    // 抽象方法:子类必须实现
    protected abstract List<Data> parseFile(String filePath);
    protected abstract void saveData(List<Data> dataList);
    
    // 钩子方法:子类可选择重写
    protected boolean shouldNotify() {
        return true;
    }
}

// 具体实现:CSV 导入
public class CsvImporter extends DataImporter {
    @Override
    protected List<Data> parseFile(String filePath) {
        System.out.println("解析 CSV 文件");
        return Arrays.asList(new Data("1"), new Data("2"));
    }
    
    @Override
    protected void saveData(List<Data> dataList) {
        System.out.println("保存 CSV 数据到数据库");
    }
}

// 具体实现:Excel 导入
public class ExcelImporter extends DataImporter {
    @Override
    protected List<Data> parseFile(String filePath) {
        System.out.println("解析 Excel 文件");
        return Arrays.asList(new Data("A"), new Data("B"));
    }
    
    @Override
    protected void saveData(List<Data> dataList) {
        System.out.println("保存 Excel 数据到数据库");
    }
    
    @Override
    protected boolean shouldNotify() {
        return false; // Excel 导入不发送通知
    }
}

// 使用
DataImporter csvImporter = new CsvImporter();
csvImporter.importData("data.csv");

框架中的应用

Spring JdbcTemplate

// JdbcTemplate 使用模板方法模式
public <T> T query(String sql, ResultSetExtractor<T> rse) {
    Connection con = DataSourceUtils.getConnection(getDataSource());
    try {
        Statement stmt = con.createStatement();
        try {
            ResultSet rs = stmt.executeQuery(sql);
            try {
                return rse.extractData(rs); // 回调实现
            } finally {
                rs.close();
            }
        } finally {
            stmt.close();
        }
    } finally {
        DataSourceUtils.releaseConnection(con, getDataSource());
    }
}

HttpServlet

// Servlet 的生命周期使用模板方法
public abstract class HttpServlet extends GenericServlet {
    protected 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); // 子类实现
        }
    }
}

优缺点

优点缺点
代码复用类数量增加
控制算法结构可能限制灵活性
符合开闭原则复杂继承层次

总结

模板方法模式是框架设计的常用模式。Spring 中的 JdbcTemplate、TransactionTemplate 都使用了这种模式。在现代 Java 中,也可以考虑使用回调接口(如 Lambda)来实现更灵活的设计。