模板方法模式

模板方法模式是一种行为设计模式,它定义了一个算法的骨架,将某些步骤延迟到子类中实现。通过模板方法,子类可以重定义算法的某些步骤,而不会改变算法的结构。

场景示例:茶(Tea)和咖啡(Coffee)的制作过程

制作茶和咖啡的过程有很多相似之处,但也有一些不同点。我们可以用模板方法模式来抽象出制作饮品的通用流程,并在子类中实现具体的操作。

制作茶和咖啡的步骤:

  1. 把水煮沸。
  2. 冲泡饮料(茶用茶叶,咖啡用咖啡粉)。
  3. 将饮料倒入杯子。
  4. 如果需要,可以添加配料(茶加柠檬,咖啡加糖和牛奶)。

代码实现:

1. 创建模板类 CaffeineBeverage

CaffeineBeverage 是一个抽象类,它包含了制作饮料的模板方法 prepareRecipe()。这个方法定义了制作饮品的骨架,而其中某些步骤由子类实现。

java 复制代码
public abstract class CaffeineBeverage {
    // 模板方法,定义了制作饮料的骨架
    public final void prepareRecipe() {
        boilWater();
        brew();
        pourInCup();
        if (customerWantsCondiments()) { // 钩子方法
            addCondiments();
        }
    }

    // 具体步骤:把水煮沸
    private void boilWater() {
        System.out.println("Boiling water");
    }

    // 具体步骤:将饮料倒入杯子
    private void pourInCup() {
        System.out.println("Pouring into cup");
    }

    // 抽象步骤:冲泡饮料
    protected abstract void brew();

    // 抽象步骤:添加配料
    protected abstract void addCondiments();

    // 钩子方法,子类可以覆盖此方法来改变算法的行为
    protected boolean customerWantsCondiments() {
        return true; // 默认添加配料
    }
}
2. 实现具体类 Tea

Tea 类继承自 CaffeineBeverage,并实现了冲泡和添加配料的具体逻辑。

java 复制代码
public class Tea extends CaffeineBeverage {
    @Override
    protected void brew() {
        System.out.println("Steeping the tea");
    }

    @Override
    protected void addCondiments() {
        System.out.println("Adding Lemon");
    }

    // 重写钩子方法,如果不需要配料
    @Override
    protected boolean customerWantsCondiments() {
        return false;  // 比如有时候顾客不想要加柠檬
    }
}
3. 实现具体类 Coffee

Coffee 类同样继承自 CaffeineBeverage,并实现了冲泡和添加配料的具体逻辑。

java 复制代码
public class Coffee extends CaffeineBeverage {
    @Override
    protected void brew() {
        System.out.println("Dripping coffee through filter");
    }

    @Override
    protected void addCondiments() {
        System.out.println("Adding Sugar and Milk");
    }
}
4. 测试客户端

在客户端中,我们可以通过调用 prepareRecipe() 方法来制作茶和咖啡。

java 复制代码
public class BeverageTest {
    public static void main(String[] args) {
        System.out.println("Making tea...");
        CaffeineBeverage tea = new Tea();
        tea.prepareRecipe();

        System.out.println("\nMaking coffee...");
        CaffeineBeverage coffee = new Coffee();
        coffee.prepareRecipe();
    }
}

输出结果

plaintext 复制代码
Making tea...
Boiling water
Steeping the tea
Pouring into cup

Making coffee...
Boiling water
Dripping coffee through filter
Pouring into cup
Adding Sugar and Milk

代码解释

  1. CaffeineBeverage :这个抽象类定义了制作饮料的模板方法 prepareRecipe(),这个方法包含制作饮品的通用步骤。brew()addCondiments() 是抽象方法,由具体的子类实现。

  2. TeaCoffee :这两个类继承自 CaffeineBeverage 并实现了冲泡和添加配料的具体逻辑。比如,Tea 中冲泡茶叶,Coffee 中使用滤器冲泡咖啡。

  3. 钩子方法customerWantsCondiments() 是一个可选的钩子方法,子类可以覆盖它来决定是否添加配料。比如,在 Tea 中,我们重写了该方法,返回 false,表示不需要配料。

  4. 模板方法prepareRecipe() 是模板方法,它控制了制作饮料的整个流程,子类无法改变这个流程的结构,只能改变其中的部分实现。

优点

  • 代码复用:公共的操作步骤在模板类中实现,避免代码重复。
  • 灵活性:通过钩子方法可以让子类决定是否执行某些步骤,而不会影响整体的算法结构。

使用场景

  • 适合具有统一流程结构、但某些步骤不同的场景。
  • 需要对算法步骤进行扩展或修改时,避免重复代码。

通过模板方法模式,可以灵活地定义算法的通用框架,并将部分实现留给子类完成,增加了代码的可扩展性和灵活性。

相关推荐
hdsoft_huge2 小时前
Java & Spring Boot常见异常全解析:原因、危害、处理与防范
java·开发语言·spring boot
雨白2 小时前
Java 多线程指南:从基础用法到线程安全
android·java
Hungry_Shark2 小时前
IDEA版本控制管理之使用Gitee
java·gitee·intellij-idea
赛姐在努力.2 小时前
《IDEA 突然“三无”?三秒找回消失的绿色启动键、主菜单和项目树!》
java·intellij-idea
猎板PCB黄浩3 小时前
从废料到碳减排:猎板 PCB 埋容埋阻的绿色制造革命,如何实现环保与性能双赢
java·服务器·制造
ZzzK,3 小时前
JAVA虚拟机(JVM)
java·linux·jvm
西红柿维生素3 小时前
JVM相关总结
java·jvm·算法
coderxiaohan4 小时前
【C++】类和对象1
java·开发语言·c++
ChillJavaGuy4 小时前
常见限流算法详解与对比
java·算法·限流算法
寻星探路5 小时前
数据库造神计划第六天---增删改查(CRUD)(2)
java·大数据·数据库