模板方法设计模式

模板方法设计模式是一种行为型设计模式,它定义了一个算法的骨架,但将某些步骤的具体实现延迟到子类中。这样可以在不改变算法整体结构的前提下,允许子类重新定义某些步骤。这种模式的核心是"封装不变部分,扩展可变部分",适用于需要复用算法框架的场景。

核心思想
  • 抽象类(Abstract Class) :定义算法的骨架,包含一个或多个模板方法(通常用final修饰,防止子类覆盖)。模板方法调用一系列抽象方法或钩子方法(hook methods)。
  • 具体子类(Concrete Class):继承抽象类,并实现抽象方法或覆盖钩子方法,以提供特定步骤的行为。
  • 关键特性 :
    • 模板方法控制算法流程。
    • 抽象方法强制子类实现必要步骤。
    • 钩子方法提供可选扩展点(默认实现可为空)。
Java实现示例

以下是一个简单的Java代码示例,演示模板方法模式:我们模拟一个"数据处理"算法,其中数据加载和保存步骤由子类自定义。

java 复制代码
// 抽象类定义算法骨架
abstract class DataProcessor {
    // 模板方法(final防止覆盖)
    public final void processData() {
        loadData();
        process();
        saveData();
    }

    // 抽象方法:必须由子类实现
    protected abstract void loadData();
    protected abstract void saveData();

    // 钩子方法:默认实现,子类可选覆盖
    protected void process() {
        System.out.println("处理数据中...");
    }
}

// 具体子类1:文件数据处理
class FileDataProcessor extends DataProcessor {
    protected void loadData() {
        System.out.println("从文件加载数据");
    }

    protected void saveData() {
        System.out.println("保存数据到文件");
    }
}

// 具体子类2:数据库数据处理
class DatabaseDataProcessor extends DataProcessor {
    protected void loadData() {
        System.out.println("从数据库加载数据");
    }

    protected void saveData() {
        System.out.println("保存数据到数据库");
    }

    // 覆盖钩子方法,添加自定义处理
    protected void process() {
        System.out.println("执行数据库优化处理");
    }
}

// 客户端代码示例
public class Main {
    public static void main(String[] args) {
        DataProcessor fileProcessor = new FileDataProcessor();
        fileProcessor.processData(); // 输出:从文件加载数据、处理数据中...、保存数据到文件

        DataProcessor dbProcessor = new DatabaseDataProcessor();
        dbProcessor.processData(); // 输出:从数据库加载数据、执行数据库优化处理、保存数据到数据库
    }
}
优点
  • 代码复用:算法骨架在抽象类中定义,避免重复代码。
  • 灵活性:子类可轻松扩展或修改特定步骤,而不影响整体流程。
  • 控制反转:抽象类控制算法流程,子类只负责实现细节。
  • 易于维护:修改算法结构时,只需调整抽象类,不影响子类。
缺点
  • 子类依赖:每个新行为都需要创建子类,可能导致类数量膨胀。
  • 限制性:模板方法固定了算法步骤,如果需求变化大,可能不够灵活。
  • 复杂度:过度使用钩子方法会使代码难以理解。
应用场景
  • 框架开发:如Spring框架中的JdbcTemplate,模板方法处理数据库连接和事务,子类实现SQL执行。
  • 算法标准化:在游戏开发中,定义游戏循环(加载、更新、渲染),子类实现具体逻辑。
  • 工作流引擎:如审批流程,抽象类定义步骤(提交、审核、完成),子类处理业务细节。
  • 测试框架:JUnit的TestCase类使用模板方法定义测试生命周期(setup、test、teardown)。

在实际开发中,确保模板方法简洁,避免过度抽象。优先使用钩子方法提供扩展点,而非强制所有子类实现多余步骤。

相关推荐
nice_lcj5202 小时前
Java Lambda 表达式入门:怎么写、怎么用、常用方法有哪些
java·开发语言·后端·面试
码农小河662 小时前
基于SSM+JSP+MySQL的在线医疗服务系统的设计与实现
java·开发语言·mysql
SL_staff3 小时前
从配置失效到逻辑复用:JVS-Logic 如何构建可治理的业务编排中枢
java·spring·产品
特立独行的猫A3 小时前
一份 Markdown 发十个平台:cspub 一稿多投
java·后端·python
文丑颜不良啊4 小时前
LeetCode1961~1980题目解析
java·leetcode
文丑颜不良啊5 小时前
LeetCode2001~2020题目解析
java·leetcode
用户3721574261355 小时前
Java 批量提取 Word 文档中的图片并保存到本地
java
SL_staff5 小时前
BI项目失败率90%?JVS如何用三阶闭环构建可落地的数据生产力平台
java·开源·全栈
nice_lcj5207 小时前
ThreadLocal 入门:它是怎么隔离数据的、为什么会导致内存泄漏
java·开发语言·后端·面试·并发编程·内存泄漏·threadlocal
紧跟先前的步伐7 小时前
Go AI Agent 实战 28|Agent 的预算、超时与停止条件
开发语言·人工智能·后端·ai·golang