模板方法模式

模板方法模式

文章目录

什么是模板方法模式

模板方法模式,定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤

重复 = 易错 + 难改

继承

我们既然用了继承,并且肯定这个继承有意义,就应该要成为子类的模板,所有重复的代码都应该要上升到父类去,而不是让每个子类都去重复。
模板方法登场,当我们要完成在某一细节层次一致的一个过程或一系列步骤,但其个别步骤在更详细的层次上的实现可能不同时,我们通常考虑用模板方法模式来处理
模板方法模式是通过把不变行为搬移到超类,去除子类中的重复代码来体现它的优势
模板方法模式就是提供了一个很好的代码复用平台
当不变的和可变的行为在方法的子类实现中混合在一起的时候,不变的行为就会在子类中重复出现。我们通过模板方法模式把这些行为搬移到单一的地方,这样就帮助子类摆脱重复的不变行为的纠缠

示例

模板方法模式是一种行为设计模式,它在一个抽象类中定义了一个算法的框架,允许子类在不改变结构的情况下重写算法的特定步骤。以下是一个使用 Java 实现模板方法模式的示例,以制作咖啡(Coffee)为例:

1.定义一个抽象的咖啡基类 Coffee,其中包含一个模板方法 makeCoffee(),它定义了制作咖啡的基本流程。在这个模板方法中,调用了若干个抽象方法(钩子方法),这些方法将在子类中实现具体的步骤:

java 复制代码
public abstract class Coffee {
    public final void makeCoffee() {
        boilWater();
        brewCoffeeGrinds();
        pourInCup();
        addCondiments();
    }

    // 钩子方法,子类可以选择是否覆盖
    protected void boilWater() {
        System.out.println("Boiling water...");
    }

    // 钩子方法,子类必须覆盖
    protected abstract void brewCoffeeGrinds();

    // 钩子方法,子类可以选择是否覆盖
    protected void pourInCup() {
        System.out.println("Pouring coffee into a cup...");
    }

    // 钩子方法,子类可以选择是否覆盖
    protected void addCondiments() {
        System.out.println("Adding sugar and milk...");
    }
}

2.创建具体的咖啡子类,如 Espresso 和 Latte,它们继承自 Coffee 类并实现或覆盖父类中的抽象方法:

java 复制代码
public class Espresso extends Coffee {
    @Override
    protected void brewCoffeeGrinds() {
        System.out.println("Brewing espresso...");
    }

    // 可选地,覆盖父类的默认实现
    @Override
    protected void addCondiments() {
        System.out.println("Adding a shot of vanilla syrup...");
    }
}
java 复制代码
public class Latte extends Coffee {
    @Override
    protected void brewCoffeeGrinds() {
        System.out.println("Brewing latte...");
    }

    // 可选地,覆盖父类的默认实现
    @Override
    protected void addCondiments() {
        System.out.println("Frothing milk and pouring it over the coffee...");
    }
}

3.在客户端代码中,创建具体的咖啡子类对象并调用模板方法 makeCoffee():

java 复制代码
public class CoffeeShop {
    public static void main(String[] args) {
        Coffee espresso = new Espresso();
        espresso.makeCoffee();

        System.out.println("\n---\n");

        Coffee latte = new Latte();
        latte.makeCoffee();
    }
}

运行 CoffeeShop 类的 main 方法,输出结果应为:

复制代码
Boiling water...
Brewing espresso...
Pouring coffee into a cup...
Adding a shot of vanilla syrup...

---

Boiling water...
Brewing latte...

总结

  1. 定义抽象类,并定义好具体的流程
  2. 具体的流程可以选择性的是否重写,从而达到具体某个步骤不通逻辑处理的实现
相关推荐
你我约定有三9 分钟前
软件启动时加配置文件 vs 不加配置文件
java·分布式·zookeeper
27^×17 分钟前
Java 内存模型与垃圾回收机制详解
java·开发语言
syty202018 分钟前
flink 伪代码
java·windows·flink
max50060032 分钟前
本地部署开源数据生成器项目实战指南
开发语言·人工智能·python·深度学习·算法·开源
q5673152334 分钟前
手把手教你用Go打造带可视化的网络爬虫
开发语言·爬虫·信息可视化·golang
Bling_Bling_139 分钟前
面试常考:js中 Map和 Object 的区别
开发语言·前端·javascript
你好~每一天1 小时前
2025年B端产品经理进阶指南:掌握这些计算机专业技能,决胜职场!
java·人工智能·经验分享·学习·产品经理·大学生
程序喵大人1 小时前
写C++十年,我现在怎么设计类和模块?(附真实项目结构)
开发语言·c++·类和模板
黄焖鸡能干四碗2 小时前
信息系统安全保护措施文件方案
大数据·开发语言·人工智能·web安全·制造
一只韩非子2 小时前
Spring AI Alibaba 快速上手教程:10 分钟接入大模型
java·后端·ai编程