设计模式之模板方法模式:咖啡,茶,和代码

embedded/2024/12/29 11:11:26/

在这里插入图片描述

~犬📰余~

“我欲贱而贵,愚而智,贫而富,可乎?
曰:其唯学乎”

一、模板方法模式概述

\quad 在我们的日常生活中,经常会遇到这样的场景:不同的事物,却有着相似的处理流程。比如泡茶和冲咖啡,虽然最终的饮品不同,但它们的制作步骤非常相似:都需要烧水、准备容器、加入原料、倒入热水等。这种情况下,我们就可以使用模板方法模式来优雅地解决问题。

\quad 模板方法模式是一种行为型设计模式,它定义了一个框架,将某些步骤延迟到子类中实现。模板方法使得子类可以不改变算法的结构即可重定义该算法的某些特定步骤。这就好比我们在制作饮品时,烧水、准备容器这些步骤是固定的,而具体加入什么原料则由具体的饮品决定。
图片

二、模板方法模式的角色组成

\quad 模板方法模式中主要包含两个角色:抽象类和具体类。就像一个饮品制作流程的"说明书",抽象类规定了整体的制作步骤,而具体类则负责填充每个步骤的具体细节。

  • 抽象类(AbstractClass):整个模式的核心,它负责定义算法的骨架,也就是那些所有子类共有的步骤。在我们的饮品示例中,它就像是一个通用的制作流程:准备容器、烧水、放入原料、倒入热水等。这些步骤的执行顺序是固定的,但具体如何执行可能因饮品而异。
  • 具体类(ConcreteClass):负责实现那些在抽象类中声明的抽象步骤。比如咖啡和茶虽然都需要放入原料,但一个放入咖啡粉,一个放入茶叶,这就是由具体类来决定的。这样的设计让我们能够在保持整体流程不变的情况下,轻松地添加新的饮品种类。

三、模板方法模式案例

\quad 让我们通过一个制作饮品的例子来深入理解模板方法模式。在这个例子中,我们将实现一个饮品制作的框架,它可以用来制作咖啡和茶。虽然这些饮品的具体制作步骤不同,但它们都遵循相似的制作流程。
图片
\quad 首先,我们定义一个抽象的饮品类:

java">public abstract class AbstractBeverage {// 模板方法public final void prepareBeverage() {boilWater();addIngredients();pourInCup();if (customerWantsCondiments()) {addCondiments();}}// 基本方法 - 共同的步骤protected void boilWater() {System.out.println("将水煮沸");}// 抽象方法 - 由子类实现的步骤protected abstract void addIngredients();protected void pourInCup() {System.out.println("倒入杯中");}// 钩子方法protected boolean customerWantsCondiments() {return true;}protected void addCondiments() {// 默认实现}
}

\quad 然后,我们来实现具体的咖啡和茶类:

java">public class Coffee extends AbstractBeverage {@Overrideprotected void addIngredients() {System.out.println("加入咖啡粉");}@Overrideprotected void addCondiments() {System.out.println("加入糖和牛奶");}
}public class Tea extends AbstractBeverage {@Overrideprotected void addIngredients() {System.out.println("加入茶叶");}@Overrideprotected void addCondiments() {System.out.println("加入柠檬");}@Overrideprotected boolean customerWantsCondiments() {System.out.println("询问客户是否需要加柠檬");return false; // 示例中默认不加调料}
}

\quad 最后是测试类:

java">public class Test {public static void main(String[] args) {AbstractBeverage beverage = new Coffee();        beverage.prepareBeverage();  beverage = new Tea();        beverage.prepareBeverage();    }
}

\quad 以及测试结果:
图片

四、模板方法模式优缺点

4.1. 优点

\quad 能够让我们在不改变算法整体结构的情况下,通过继承来改变算法中特定的步骤。就像我们的饮品示例,如果要增加新的饮品种类,只需要创建一个新的子类,实现特定的步骤即可,而不需要修改现有的代码。这体现了面向对象设计中的"开闭原则"。

4.2. 缺点

\quad 首先,抽象类中的模板方法需要考虑到所有可能的变化,这使得抽象类的职责可能过重。其次,它是基于继承机制的,这意味着每个不同的实现都需要一个新的子类,当变化过多时,可能会导致类的数量急剧增加。

五、模板方法模式的适用场景

\quad 模板方法模式最适合应用在一系列算法或过程有共同骨架,但具体步骤不同的场合。比如一个软件系统的数据导入功能,不管是导入Excel、CSV还是XML文件,都需要经过文件验证、数据解析、数据转换、数据存储等步骤,只是每种格式的具体实现细节不同。这时使用模板方法模式就能很好地复用共同的处理逻辑。
\quad 在框架设计中,模板方法模式也被广泛使用。许多框架都通过提供抽象类来定义扩展点,让开发者通过继承实现自定义的业务逻辑。这样既保证了框架的通用性,又提供了足够的灵活性。

六、总结

\quad 模板方法模式通过把不变的行为搬移到超类,去除子类中的重复代码来体现它的优势。它是一种典型的通过继承实现的代码复用技术。在日常开发中,我们经常需要处理一些存在共同骨架的算法或流程,这时就可以考虑使用模板方法模式
\quad 通过本文的讲解和饮品制作的示例,我们可以看到模板方法模式的精髓在于"抽象出流程中的共同点,保留不同点的实现空间"。它帮助我们实现了代码的复用,同时保持了良好的扩展性。在实际应用中,这个模式不仅能够让我们的代码更加优雅,还能显著提高开发效率。不过也要注意,过度使用继承可能会带来维护上的困难,因此在使用时需要根据具体场景权衡利弊。

在这里插入图片描述

关注犬余,共同进步

技术从此不孤单

http://www.ppmy.cn/embedded/149715.html

相关文章

用 ElementUI 的日历组件 Calendar 自定义渲染

文章目录 需求分析1. 页面渲染2. 获取页面上的开始日期和结束日期3. 总的代码 需求 之前实现过一版用 ElementPlus 的日历组件 Calendar 自定义渲染&#xff0c;是在 Vue3 项目中实现的&#xff0c;现在需求在 Vue2 中也实现一版 分析 1. 页面渲染 <el-calendar v-model&q…

【每日学点鸿蒙知识】Web请求支持Http、PDF展示、APP上架应用搜索问题、APP备案不通过问题、滚动列表问题

1、HarmonyOS Web不支持http请求&#xff0c;只支持https&#xff1f; Web组件http请求失败&#xff0c;改成https是好的&#xff0c;是否可以通过配置打开http的请求 参考文档&#xff1a;https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-basic-c…

《类和对象:基础原理全解析(中篇)》

目录 一、 类成员函数的 this 指针1. this 指针的使用2. this 指针的注意事项 二、const 成员函数1. const 关键字的添加位置2. const 成员函数的使用建议 三、析构函数1. 拷贝构造函数的使用2. 使用析构函数的注意事项 四、拷贝构造函数1. 使用默认拷贝构造函数的 Stack 类2. …

从零开始学AI,完成AI 企业知识库的AI问答搭建

1&#xff1a;本地安装一个ollama玩下&#xff0c;ollama下载模型默认路径为C盘&#xff0c;但该盘空间不足。 解决方案&#xff1a;添加系统环境变量OLLAMA_MODELS&#xff0c;设置其值为新的路径。 2&#xff1a;安装完成后&#xff0c;访问http://127.0.0.1:11434/ 查看服务…

WebRTC 环境搭建

主题 本文主要描述webrtc开发过程中所需的环境搭建 环境&#xff1a; 运行环境&#xff1a;ubuntu20.04 Node.js环境搭建 安装编译 Node.js 所需的依赖包: sudo apt-get updatesudo apt-get install -y build-essential libssl-dev下载 Node.js 源码: curl -sL https://…

Android 14.0 设置默认屏幕亮度百分比

1.概述 在14.0的系统ROM产品开发中,在一些产品开发中,对于设置默认屏幕亮度和屏幕亮度百分比的功能,在开发中也是常见的功能,在10.0的平台设置可能有一些不同,一般的都是在SettingProvider中设置就可以了 在11.0以后的系统中设置默认屏幕亮度的方法就不同了,接下来具体分…

在K8S中,etcd数据库数据如何更改?

在kubernetes中&#xff0c;etcd中的数据更改主要发生在以下几个场景中&#xff1a; 1. 创建、更新和删除Kubernetes资源对象&#xff1a; 当用户在kubernetes中创建&#xff08;POST&#xff09;、更新&#xff08;PUT&#xff09;或删除&#xff08;DELETE&#xff09;一个…

解密MQTT协议:从QOS到消息传递的全方位解析

1、QoS介绍 1.1、QoS简介 使用MQTT协议的设备大部分都是运行在网络受限的环境下&#xff0c;而只依靠底层的TCP传输协议&#xff0c;并不 能完全保证消息的可靠到达。 MQTT提供了QoS机制&#xff0c;其核心是设计了多种消息交互机制来提供不同的服务质量&#xff0c;来满足…