Spring + 设计模式 (十五) 行为型 - 模板方法模式

模板方法模式

引言

模板方法模式是一种行为型设计模式,定义了一个操作的骨架,将具体步骤延迟到子类实现。它的核心是通过抽象类或接口固定算法的总体流程,同时允许子类在不改变结构的情况下定制部分步骤。就像烹饪一道菜:模板方法给出"炒菜"的通用步骤(热锅、放油、翻炒),具体食材和调料由子类决定。在企业开发中,模板方法模式常用于流程化操作,如数据处理、事务管理、请求处理等场景,兼顾代码复用和灵活性。它的魅力在于既保证了流程的稳定性,又给子类留足发挥空间。

实际开发中的用途

模板方法模式适合需要统一流程但部分步骤可定制的场景。比如,批量数据导入系统:无论导入用户数据还是订单数据,流程都是"读取文件 → 校验数据 → 持久化",但具体校验和持久化逻辑因数据类型不同。模板方法模式通过抽象类定义通用流程,子类实现差异化步骤,避免重复代码。

举个例子:开发一个报表生成系统,报表有多种类型(如PDF、Excel),但生成流程一致:加载数据 → 格式化 → 导出文件。用模板方法模式,抽象类定义流程,子类实现格式化和导出的具体逻辑。如果要加个新报表类型(比如CSV),只写个新子类,流程代码不用动,复用性和扩展性都拉满。

Spring 源码中的应用

模板方法模式在 Spring 框架中应用广泛,尤其在 Spring JDBC 的 JdbcTemplate 中体现得淋漓尽致。JdbcTemplate 封装了 JDBC 操作的通用流程(如获取连接、执行 SQL、处理结果集、关闭资源),具体查询或更新逻辑由开发者通过回调接口实现。

源码分析 :以下是 JdbcTemplateexecute 方法(引用 Spring Framework 5.3.33,路径:org.springframework.jdbc.core.JdbcTemplate),展示模板方法模式的实现:

java 复制代码
public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
    public <T> T execute(PreparedStatementCreator psc, PreparedStatementCallback<T> action) throws DataAccessException {
        Assert.notNull(psc, "PreparedStatementCreator must not be null");
        Assert.notNull(action, "PreparedStatementCallback must not be null");

        Connection con = DataSourceUtils.getConnection(obtainDataSource());
        PreparedStatement ps = null;
        try {
            ps = psc.createPreparedStatement(con);
            ResultSet rs = null;
            if (action != null) {
                T result = action.doInPreparedStatement(ps); // 子类实现的回调
                handleWarnings(ps);
                return result;
            }
            return null;
        }
        catch (SQLException ex) {
            throw translateSQLException("JdbcTemplate", ex);
        }
        finally {
            JdbcUtils.closeStatement(ps);
            DataSourceUtils.releaseConnection(con, getDataSource());
        }
    }
}

模板方法体现

  • 模板方法execute 方法定义了 JDBC 操作的固定流程(获取连接 → 创建语句 → 执行回调 → 处理异常 → 释放资源)。
  • 抽象步骤PreparedStatementCallback 接口的 doInPreparedStatement 方法由开发者实现,定制具体 SQL 执行逻辑。
  • 固定流程 :连接管理和资源释放由 JdbcTemplate 保证,子类无需关心。

解决问题JdbcTemplate 通过模板方法模式,统一了 JDBC 操作的繁琐流程,开发者只需关注业务逻辑(如 SQL 和结果处理),大大降低开发复杂度和错误率,同时保证资源管理的一致性。

Java 代码案例

以下基于 Spring Boot 实现一个报表生成系统,展示模板方法模式在企业级开发中的应用。报表生成流程包括"加载数据 → 格式化 → 导出文件",支持 PDF 和 Excel 两种格式。

代码实现

java 复制代码
// 抽象报表生成器
public abstract class ReportGenerator {

    // 模板方法,定义生成报表的固定流程
    public final void generateReport() {
        List<?> data = loadData();
        String formattedContent = formatData(data);
        exportFile(formattedContent);
    }

    // 固定步骤:加载数据
    protected List<?> loadData() {
        // 模拟从数据库加载数据
        return Arrays.asList("Data1", "Data2", "Data3");
    }

    // 抽象步骤:子类实现数据格式化
    protected abstract String formatData(List<?> data);

    // 抽象步骤:子类实现文件导出
    protected abstract void exportFile(String content);
}

// PDF 报表生成器
@Component
public class PdfReportGenerator extends ReportGenerator {

    @Override
    protected String formatData(List<?> data) {
        // 模拟 PDF 格式化
        return "PDF Report:\n" + data.stream().collect(Collectors.joining("\n"));
    }

    @Override
    protected void exportFile(String content) {
        // 模拟导出 PDF 文件
        System.out.println("Exporting PDF:\n" + content);
    }
}

// Excel 报表生成器
@Component
public class ExcelReportGenerator extends ReportGenerator {

    @Override
    protected String formatData(List<?> data) {
        // 模拟 Excel 格式化
        return "Excel Report:\n" + data.stream().collect(Collectors.joining(","));
    }

    @Override
    protected void exportFile(String content) {
        // 模拟导出 Excel 文件
        System.out.println("Exporting Excel:\n" + content);
    }
}

// 报表服务
@Service
public class ReportService {

    @Autowired
    private List<ReportGenerator> generators;

    public void generateAllReports() {
        generators.forEach(ReportGenerator::generateReport);
    }
}

代码说明

  • 模板方法体现ReportGeneratorgenerateReport 方法定义了报表生成的固定流程(加载 → 格式化 → 导出)。final 关键字确保流程不可更改。
  • 抽象步骤formatDataexportFile 由子类 PdfReportGeneratorExcelReportGenerator 实现,定制具体格式和导出逻辑。
  • 解决的问题:统一报表生成流程,减少重复代码。新增报表类型(如 CSV)只需实现新子类,符合开闭原则。
  • 好处:代码复用性高,流程逻辑集中,维护成本低。Spring 的依赖注入让扩展和管理生成器更灵活。
  • 运行方式 :通过 ReportService 调用 generateAllReports,自动执行所有报表生成器,输出 PDF 和 Excel 格式的报表。

总结

模板方法模式就像一个经验丰富的厨师,给你一份万能菜谱,关键步骤让你自由发挥。它通过固定流程减少重复代码,通过抽象步骤保证灵活性。在 Spring 的 JdbcTemplate 中,模板方法模式让 JDBC 操作变得简单而可靠,开发者只需写 SQL 和结果处理,框架搞定连接和资源管理。我们的报表案例进一步展现了它的实用性:统一的生成流程让代码清晰,新增报表类型毫不费力。

(对您有帮助 && 觉得我总结的还行) -> 受累点个免费的赞👍,谢谢

相关推荐
yio_yin6 小时前
Spring事务管理(数据一致性)
数据库·sql·spring
dear_bi_MyOnly6 小时前
【SpringBoot配置文件】
java·spring boot·后端·学习·spring·java-ee·学习方法
our_times8 小时前
2026年Java开发者破局指南:Spring AI 2.0 与 Agent 开发实战
java·人工智能·spring
杨充8 小时前
10.可测试性实战设计
设计模式·开源·代码规范
杨充8 小时前
9.重构十二式的实战
设计模式·开源·代码规范
杨充8 小时前
6.设计原则的全景图
设计模式·开源·全栈
杨充9 小时前
2.面向对象的特性
设计模式
杨充9 小时前
7.SOLID原则案例汇
设计模式·开源·全栈
杨充9 小时前
8.反模式与坏味道
设计模式·开源·代码规范
杨充9 小时前
3.接口vs抽象类比较
设计模式