设计模式之-模板方法模式,(TemplateMothed)

Template Method 是一种行为设计模式,它在父类中定义了一个算法的框架,允许子类在不改变算法结构的情况下重写算法的特定步骤。

核心思想
  • 固定算法骨架:将不变的部分(算法步骤)放到父类中实现

  • 可变部分抽象:将可能变化的部分抽象为方法,由子类实现

  • 好莱坞原则:"Don't call us, we'll call you" - 父类控制流程,子类提供实现

主要角色
  1. AbstractClass(抽象类):定义模板方法和抽象步骤

  2. ConcreteClass(具体子类):实现抽象步骤


使用Template Method模板方法模式模拟一个饮料制作系统。

场景描述

我们实现一个饮料制作系统,咖啡和茶的制作流程基本相同(煮沸水->冲泡->倒入杯子->加调料),但具体冲泡方式和调料不同。

首先定义一个抽象类

// 1. 抽象类(定义模板方法)
abstract class Beverage {
    
    // 模板方法(final防止子类覆盖算法结构)
    public final void prepareRecipe() {
        boilWater();
        brew();
        pourInCup();
        addCondiments();
    }
    
    // 通用步骤(直接实现)
    private void boilWater() {
        System.out.println("煮沸水");
    }
    
    private void pourInCup() {
        System.out.println("倒入杯子");
    }
    
    // 抽象步骤(由子类实现)
    protected abstract void brew();
    protected abstract void addCondiments();
}
具体的实现类


// 2. 具体子类:咖啡
class Coffee extends Beverage {
    @Override
    protected void brew() {
        System.out.println("用沸水冲泡咖啡粉");
    }
    
    @Override
    protected void addCondiments() {
        System.out.println("加糖和牛奶");
    }
}

// 3. 具体子类:茶
class Tea extends Beverage {
    @Override
    protected void brew() {
        System.out.println("用沸水浸泡茶叶");
    }
    
    @Override
    protected void addCondiments() {
        System.out.println("加柠檬");
    }
}
模拟这一个过程


// 4. 客户端
public class Main {
    public static void main(String[] args) {
        System.out.println("制作咖啡:");
        Beverage coffee = new Coffee();
        coffee.prepareRecipe();
        
        System.out.println("\n制作茶:");
        Beverage tea = new Tea();
        tea.prepareRecipe();
    }
}
输出结果


模式特点

  1. 模板方法

    • 必须是 final 方法,防止子类修改算法结构

    • 包含固定步骤和抽象方法调用

  2. 钩子方法(可选):

    // 在抽象类中添加钩子方法
    protected boolean customerWantsCondiments() {
        return true; // 默认加调料
    }
    
    // 修改模板方法
    public final void prepareRecipe() {
        boilWater();
        brew();
        pourInCup();
        if (customerWantsCondiments()) {
            addCondiments();
        }
    }
    
    // 子类可以覆盖钩子方法
    class Coffee extends Beverage {
        @Override
        protected boolean customerWantsCondiments() {
            return false; // 咖啡不加调料
        }
    }


模式优势

  1. 代码复用:将公共代码放在父类中

  2. 扩展可控:子类只能改变特定步骤,不能改变流程

  3. 符合开闭原则:新增饮料类型只需添加子类


实际应用场景

  1. 框架设计(如Spring的JdbcTemplate)

  2. 算法骨架固定但部分步骤可变的情况

  3. 需要控制子类扩展点的场景

Spring中的模板方法示例:

public abstract class JdbcTemplate {
    public final Object execute(String sql) {
        Connection con = getConnection();
        Statement stmt = con.createStatement();
        ResultSet rs = stmt.executeQuery(sql);
        Object result = doInStatement(rs); // 抽象方法
        release(con, stmt, rs);
        return result;
    }
    
    protected abstract Object doInStatement(ResultSet rs);
}

通过这个饮料制作的例子,你可以清晰看到模板方法模式如何固定流程框架,同时允许灵活变化具体实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值