java23种设计模式-模板方法模式

模板方法模式(Template Method Pattern)学习笔记

1. 模式定义

行为型设计模式,在抽象类中定义算法的骨架,将某些步骤延迟到子类实现。允许子类在不改变算法结构的情况下重新定义特定步骤。

2. 适用场景

✅ 存在多个相似算法流程但部分步骤不同的场景

✅ 需要固定算法执行顺序的场景

✅ 需要扩展算法特定步骤的场景

✅ 框架设计(父类控制流程,子类实现具体逻辑)

✅ 需要消除重复代码(多个子类有相同结构)

3. 模式结构

<<abstract>> AbstractClass +templateMethod() +step1() +step2() +step3() ConcreteClassA +step1() +step2() ConcreteClassB +step1() +step2() +step3()

4. 核心角色

角色 说明
AbstractClass 抽象类,定义模板方法和算法步骤(抽象方法/具体方法/钩子方法)
ConcreteClass 具体子类,实现抽象步骤,可选覆盖默认实现或钩子方法

5. 代码示例

5.1 饮料制作示例

java 复制代码
// 抽象类
abstract class BeverageTemplate {
    
    // 模板方法(final防止子类覆盖)
    public final void prepareBeverage() {
        boilWater();
        brew();
        pourInCup();
        if (needCondiments()) {
            addCondiments();
        }
    }
    
    // 通用步骤实现
    private void boilWater() {
        System.out.println("煮沸水");
    }
    
    private void pourInCup() {
        System.out.println("倒入杯子");
    }
    
    // 抽象方法(必须实现)
    protected abstract void brew();
    
    protected abstract void addCondiments();
    
    // 钩子方法(可选覆盖)
    protected boolean needCondiments() {
        return true;
    }
}

// 具体子类
class Coffee extends BeverageTemplate {
    @Override
    protected void brew() {
        System.out.println("冲泡咖啡粉");
    }

    @Override
    protected void addCondiments() {
        System.out.println("加入糖和牛奶");
    }
    
    @Override
    protected boolean needCondiments() {
        return false; // 示例:咖啡不要调料
    }
}

class Tea extends BeverageTemplate {
    @Override
    protected void brew() {
        System.out.println("浸泡茶叶");
    }

    @Override
    protected void addCondiments() {
        System.out.println("加入柠檬");
    }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        BeverageTemplate coffee = new Coffee();
        coffee.prepareBeverage();
        
        System.out.println("\n===============\n");
        
        BeverageTemplate tea = new Tea();
        tea.prepareBeverage();
    }
}

6. 模式变种

  1. 钩子方法(Hook Methods)

    在抽象类中提供空实现或默认返回true的方法,子类可选择覆盖来控制流程

    java 复制代码
    protected boolean validate() {
        return true; // 默认验证通过
    }
  2. 模板方法重载

    提供多个版本的模板方法应对不同场景

    java 复制代码
    public final void process(boolean isQuickMode) {
        if (isQuickMode) {
            step1();
            step3();
        } else {
            templateMethod();
        }
    }

7. 优缺点分析

✔️ 优点

  • 封装不变部分,扩展可变部分
  • 父类控制算法结构,子类专注细节实现
  • 代码复用率高,减少重复代码
  • 符合开闭原则(通过扩展增加新实现)

缺点

  • 每增加一个实现需要新建子类,可能增加系统复杂度
  • 父类修改可能影响所有子类
  • 继承关系限制了灵活性(可通过组合+策略模式优化)

8. 相关模式对比

模式 目的 关键区别
策略模式 封装算法族 使用组合实现,更灵活
工厂方法模式 创建对象 属于创建型模式
建造者模式 分步构建对象 关注对象创建过程
命令模式 封装请求 将操作封装为对象

9. 实际应用案例

  • Java Servlet的service()方法
  • Spring框架的JdbcTemplate
  • Hibernate的HibernateTemplate
  • Java集合框架的AbstractList/AbstractSet
  • AWT的WindowAdapter(适配器模式+模板方法)
  • Junit的TestCase生命周期方法(setUp()/tearDown())

10. 最佳实践建议

  1. 模板方法声明为final:防止子类重写算法结构
  2. 合理使用钩子方法:在关键扩展点提供可控覆盖
  3. 控制抽象方法数量:避免过多步骤导致子类实现困难
  4. 结合其他模式使用
    • 与工厂方法模式结合创建步骤所需对象
    • 与策略模式结合替换特定算法步骤
  5. 优先使用组合:当需要突破单继承限制时,改用策略模式
  6. 文档注释:明确说明每个步骤的作用和调用顺序

11. 扩展应用示例(Spring JdbcTemplate)

java 复制代码
public abstract class JdbcTemplate {
    
    public final Object execute(String sql) {
        Connection con = null;
        try {
            con = getConnection();
            PreparedStatement ps = con.prepareStatement(sql);
            setParameters(ps); // 抽象方法
            ps.execute();
            return handleResult(ps); // 抽象方法
        } finally {
            releaseConnection(con);
        }
    }
    
    protected abstract void setParameters(PreparedStatement ps) throws SQLException;
    
    protected abstract Object handleResult(Statement stmt) throws SQLException;
    
    // ...其他通用方法...
}

// 使用示例
new JdbcTemplate() {
    @Override
    protected void setParameters(PreparedStatement ps) {
        ps.setString(1, "paramValue");
    }
    
    @Override
    protected Object handleResult(Statement stmt) {
        return ((PreparedStatement)stmt).getResultSet();
    }
}.execute("SELECT * FROM table WHERE col = ?");

📐 设计原则体现

  1. 好莱坞原则(Don't call us, we'll call you):父类控制流程,子类只需实现特定步骤
  2. 开闭原则(OCP):通过扩展子类增加新实现,无需修改现有代码
  3. 单一职责原则(SRP):将算法步骤拆分到不同方法

通过模板方法模式,可以有效管理复杂流程的标准化实现,特别适合框架开发和企业级应用中的通用流程控制场景。

相关推荐
重生之后端学习22 分钟前
02-前端Web开发(JS+Vue+Ajax)
java·开发语言·前端·javascript·vue.js
字节源流6 小时前
关于maven的依赖下不下来的问题
java·maven
pjx9877 小时前
服务间的“握手”:OpenFeign声明式调用与客户端负载均衡
java·运维·spring·负载均衡
prinrf('千寻)7 小时前
MyBatis-Plus 的 updateById 方法不更新 null 值属性的问题
java·开发语言·mybatis
老华带你飞7 小时前
实习记录小程序|基于SSM+Vue的实习记录小程序设计与实现(源码+数据库+文档)
java·数据库·spring boot·小程序·论文·毕设·实习记录小程序
在未来等你8 小时前
互联网大厂Java求职面试:AI与大模型应用集成及云原生挑战
java·微服务·ai·kubernetes·大模型·embedding·spring ai
源码技术栈8 小时前
SaaS基于云计算、大数据的Java云HIS平台信息化系统源码
java·大数据·云计算·云his·his系统·云医院·区域his
编程、小哥哥8 小时前
互联网大厂Java面试:从Spring Boot到微服务架构的技术深挖
java·spring boot·redis·微服务·prometheus·面试技巧
揽你·入怀9 小时前
数据结构:ArrayList简单实现与常见操作实例详解
java·开发语言
okok__TXF9 小时前
SpringBoot3+AI
java·人工智能·spring