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 和结果处理,框架搞定连接和资源管理。我们的报表案例进一步展现了它的实用性:统一的生成流程让代码清晰,新增报表类型毫不费力。

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

相关推荐
RationalDysaniaer5 分钟前
Go设计模式-观察者模式
观察者模式·设计模式·golang
千千寰宇35 分钟前
[设计模式/Java] 设计模式之解释器模式【27】
数据库·设计模式
麓殇⊙1 小时前
设计模式-- 原型模式详解
设计模式·原型模式
电子科技圈1 小时前
XMOS空间音频——在任何设备上都能提供3D沉浸式空间音频且实现更安全地聆听
经验分享·设计模式·性能优化·计算机外设·音视频
智想天开1 小时前
11.原型模式:思考与解读
设计模式·原型模式
XiaoLeisj2 小时前
【设计模式】深入解析代理模式(委托模式):代理模式思想、静态模式和动态模式定义与区别、静态代理模式代码实现
java·spring boot·后端·spring·设计模式·代理模式·委托模式
pwzs2 小时前
常见的 Spring Boot 注解汇总
java·spring boot·后端·spring
非ban必选3 小时前
spring-ai使用Document存储至milvus的数据结构
前端·spring·milvus
无业哥4 小时前
Mac搭建Spring5源码环境
spring
星星点点洲6 小时前
【设计模式区别】装饰器模式和适配器模式区别
设计模式·适配器模式·装饰器模式