Java模版模式

一、参考文档

模板模式 | 菜鸟教程https://www.runoob.com/design-pattern/template-pattern.html

二、案例讲解

[]~( ̄▽ ̄)~*今天请大家喝下午茶~

现在选择你的饮料(Beverage):

coffeepepsi-colateaiceredtea

2.1、预制制作步骤(父类):
 public final void prepareRecipe() { //模版方法
        DistributeCups();  //固定具体方法 发杯子
        brew();            //抽象方法 放茶叶、放咖啡豆、放可乐
        pourInCup();        //固定具体方法 倒水
        
        if (customerSugars()) {  //抽象 要不要放糖
            addSugars();
        }
        
        if (customerIce()) {    //抽象 要不要放糖
            addIce();
        }
    }

水水方法(模版):发杯子、冲泡、倒入杯子、私人订制(钩子方法):加糖、加冰

    // 具体步骤:发杯子
    public void DistributeCups() {
        System.out.println("发给你个杯子");
    }

    // 抽象步骤:是否加热
    public abstract void brew();

    // 具体步骤:倒入杯子
    public void pourInCup() {
        System.out.println("倒入杯子");
    }

    // 抽象步骤:添加小料
    public abstract void addSugars();

    public abstract void addIce();


    // 钩子方法:是否添加小料
    public boolean customerSugars() {
        return true;
    }

    public boolean customerIce() {
        return true;
    }
2.2、子类配置

你是个特务要隐藏自己,你选了普通的coffee、tea

//咖啡
public class Coffee extends Beverage {
    @Override
    public void brew() {
        System.out.println("***研磨咖啡豆,萃取***");
    }
    @Override
    public void addSugars() {
        System.out.println("***加糖、加奶***");
    }
    @Override
    public void addIce() {
        System.out.println("***不加冰***");
    }
}
// 茶类
public class Tea extends Beverage {
    @Override
    public void brew() {
        System.out.println("***加点毛尖,热水冲泡***");
    }
    @Override
    public void addSugars() {
        System.out.println("***不加糖***");
    }
    @Override
    public void addIce() {
        System.out.println("***不加冰***");
    }
}

你是个美食家,你对下午茶有要求,唐牛才是食神,pepsi-cola要加冰,使用Hook(钩子)方法

public class IceTeaHook extends Beverage{
    @Override
    public void brew() {
        System.out.println("***加入茶包、柠檬***");
    }

    @Override
    public void addSugars() {
        System.out.println("***加糖***");
    }

    @Override
    public void addIce() {
        System.out.println("***加入冰块***");
    }

    // 重写钩子方法,允许用户决定是否添加调料
    @Override
    public boolean customerSugars() {
        String answer = getUserInput1();
        return answer.toLowerCase().startsWith("y");
    }

    public boolean customerIce() {
        String answer = getUserInput2();
        return answer.toLowerCase().startsWith("y");
    }

    private String getUserInput1() {
        String answer = null;
        System.out.print("是否需要加糖 (y/n)? ");
        Scanner scanner = new Scanner(System.in);
        answer = scanner.nextLine();

        if (answer == null) {
            return "no";
        }
        return answer;
    }

    private String getUserInput2() {
        String answer = null;
        System.out.print("是否需要加冰 (y/n)? ");
        Scanner scanner = new Scanner(System.in);
        answer = scanner.nextLine();

        if (answer == null) {
            return "no";
        }
        return answer;
    }
}
public class IceColaHook extends Beverage{
    @Override
    public void brew() {
        System.out.println("***加入百事可乐***");
    }

    @Override
    public void addSugars() {
        System.out.println("***加糖***");
    }

    @Override
    public void addIce() {
        System.out.println("***加入冰块***");
    }

    // 重写钩子方法,允许用户决定是否添加调料
    @Override
    public boolean customerSugars() {
        String answer = getUserInput1();
        return answer.toLowerCase().startsWith("y");
    }

    public boolean customerIce() {
        String answer = getUserInput2();
        return answer.toLowerCase().startsWith("y");
    }

    private String getUserInput1() {
        String answer = null;
        System.out.print("是否需要加糖 (y/n)? ");
        Scanner scanner = new Scanner(System.in);
        answer = scanner.nextLine();

        if (answer == null) {
            return "no";
        }
        return answer;
    }

    private String getUserInput2() {
        String answer = null;
        System.out.print("是否需要加冰 (y/n)? ");
        Scanner scanner = new Scanner(System.in);
        answer = scanner.nextLine();
        scanner.close();
        if (answer == null) {
            return "no";
        }
        return answer;
    }
}
2.3运行与分析
// 测试类
public class BeverageTestDrive {
    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();

        System.out.println("\n--- 冰红茶 ---");
        Beverage iceTeaHook = new IceTeaHook();
        iceTeaHook.prepareRecipe();

        System.out.println("\n--- 可乐 ---");
        Beverage iceColaHook = new IceTeaHook();
        iceTeaHook.prepareRecipe();
    }
}    

三、拓展模版模式与工厂模式的区别

设计模式核心思想实现方式应用场景
模板模式固定框架,子类实现细节继承 + 方法重写多个子类有共同的算法结构
工厂模式封装对象创建工厂类或方法解耦对象的创建和使用
3.1核心区别
  • 模板模式

    • 行为模式:关注算法的结构和步骤复用。
    • 子类扩展:子类重写父类的抽象方法来实现特定步骤。
    • 算法流程:父类控制整体流程,子类提供部分实现。
  • 工厂模式

    • 创建模式:关注对象的创建过程。
    • 对象创建:将对象创建逻辑封装在工厂类中,客户端不直接实例化对象。
    • 解耦依赖:降低客户端与具体产品类的耦合度。
3.2案例对比
  • 模板模式:饮料冲泡流程(步骤固定,细节由子类实现)。
  • 工厂模式:创建不同类型的交通工具(汽车、飞机、轮船)。

四、账单

Excuse me, sir. Your bill, please.点赞投币一键三连~

( • 人 • )ԅ(≖ᴗ≖ԅ)耍流氓( • 人 • )ԅ(≖ᴗ≖ԅ)耍流氓

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值