行为模式-模板方法模式

定义:

        Define the skeleton of an algorithm in an operation,deferring some steps to subclasses.Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.(定义一个操作中的算法的框架,而将一些步骤延迟到子类中。使得子类可以不改 变一个算法的结构即可重定义该算法的某些特定步骤。)

模板方法模式通用类图

        模板方法设计模式的核心思想是“定义算法骨架,将可变部分延迟到子类实现”。它将算法中不变的部分封装在抽象类的模板方法中,而将可变的部分抽象成抽象方法或钩子方法,由子类具体实现。这样可以避免代码重复,同时允许子类在不改变算法整体结构的情况下,对某些步骤进行定制化实现。

角色:

模板方法模式包含以下几个核心角色:

1、抽象类(Abstract Class)

        抽象类定义了一个模板方法,该方法包含了算法的骨架,具体步骤由一系列方法调用组成。这些方法可以是抽象方法、具体方法或钩子方法:

  1. 抽象方法:由抽象类声明,具体实现由子类完成。
  2. 具体方法:在抽象类中已经实现,子类可以直接使用或重写。
  3. 钩子方法:在抽象类中提供默认实现,子类可以选择重写或不重写。钩子方法通常用于控制算法的流程。

2、具体子类(Concrete Class)

        具体子类继承自抽象类,实现抽象类中的抽象方法,必要时重写钩子方法,以实现特定的业务逻辑。具体子类不改变算法的结构,只负责实现算法中的某些步骤。

代码示例:

        咖啡和茶的制作过程有相似的步骤:烧水、冲泡、倒入杯中、添加调料。使用模板方法设计模式实现这两种饮品的制作过程。

// 抽象类:饮品制作

public abstract class Beverage {// 模板方法:定义制作饮品的算法骨架public final void prepareRecipe() {boilWater();brew();pourInCup();if (customerWantsCondiments()) {addCondiments();}}// 具体方法:烧水protected final void boilWater() {System.out.println("烧开水");}// 抽象方法:冲泡protected abstract void brew();// 具体方法:倒入杯中protected final void pourInCup() {System.out.println("倒入杯中");}// 抽象方法:添加调料protected abstract void addCondiments();// 钩子方法:是否添加调料,默认添加protected boolean customerWantsCondiments() {return true;}}

// 具体子类:咖啡

public class Coffee extends Beverage {@Overrideprotected void brew() {System.out.println("冲泡咖啡粉");}@Overrideprotected void addCondiments() {System.out.println("添加糖和牛奶");}}

// 具体子类:茶

public class Tea extends Beverage {@Overrideprotected void brew() {System.out.println("浸泡茶叶");}@Overrideprotected void addCondiments() {System.out.println("添加柠檬");}// 重写钩子方法,自定义是否添加调料@Overrideprotected boolean customerWantsCondiments() {// 模拟用户选择return Math.random() > 0.5;}}

// 客户端代码

public class BeverageClient {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.提高代码复用性:将通用的算法结构放在抽象类中,避免了在多个子类中重复实现相同的代码,提高了代码的复用性。

2.简化子类实现:子类只需实现抽象类中定义的抽象方法和需要重写的钩子方法,而不需要关心算法的整体结构,简化了子类的实现。

3.便于控制算法流程:模板方法模式将算法的控制权集中在抽象类中,子类只能在允许的范围内进行扩展,便于控制算法的流程和行为。

4.符合开闭原则:当需要修改或扩展算法的某些步骤时,只需创建新的子类,而不需要修改抽象类的代码,符合开闭原则。


缺点:

1.限制子类灵活性:模板方法模式通过继承实现代码复用,子类必须遵循抽象类定义的算法结构,可能会限制子类的灵活性。

2.增加类的数量:随着算法步骤的增加,抽象类和子类的数量可能会增多,导致系统的类层次结构变得复杂,增加了代码的理解和维护难度。

3.父类与子类耦合度较高:模板方法模式中,抽象类定义了算法的骨架,子类依赖于抽象类的实现。如果抽象类发生变化,可能会影响到所有的子类,导致父类与子类之间的耦合度较高。


使用场景:

(一)多个算法有相似结构的场景

        当多个算法或操作具有相似的结构,但某些步骤的实现方式不同时,可以使用模板方法设计模式。将通用的算法结构放在抽象类中,而将不同的步骤实现延迟到子类中,避免代码重复。

(二)需要控制子类扩展的场景

        模板方法模式允许在不改变算法整体结构的情况下,通过子类来扩展或修改算法的某些步骤。抽象类可以定义哪些步骤是必须实现的(抽象方法),哪些步骤是可以选择性实现的(钩子方法),从而控制子类的扩展方式。

(三)希望提高代码复用性的场景

        模板方法设计模式通过继承实现代码复用,将通用的代码放在抽象类中,而将特殊的代码放在子类中。这样可以减少代码冗余,提高代码的复用性和可维护性。

(四)框架设计场景

        在框架设计中,模板方法模式经常被用来定义框架的核心流程,而将一些具体的实现细节留给开发者。例如,Java 的 Servlet API 中,HttpServlet 类就使用了模板方法模式,定义了处理 HTTP 请求的基本流程,开发者只需重写 doGet()、doPost() 等方法即可。 

        模板方法设计模式通过定义算法的骨架,将可变部分延迟到子类实现,为软件开发提供了一种优雅的代码复用和扩展方式。它在多个领域都有广泛的应用,如游戏开发中的角色行为模式、软件开发中的框架设计等。合理运用模板方法设计模式,可以使代码更加简洁、灵活和易于维护。然而,在使用时也需要注意其缺点,避免过度使用导致类层次结构复杂。通过权衡利弊,我们可以在适当的场景下使用模板方法模式,发挥其最大的优势。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/94631.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/94631.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java集合遍历练习题

以下是10道难度递增的集合遍历练习题,涵盖List、Set、Map的各种遍历方式,包含解题思路、代码实现和输出结果: 练习题1:基础遍历 - ArrayList的for-each遍历 题目:创建一个存储5个字符串的ArrayList(元素为&…

深度学习·ZegclipClip-RC

Zegclip 获取图像的特殊编码:使用prompt tuning的技术,目的是减少过拟合和计算量。调整文本编码:使用RD关系描述符,将每一个文本对应的[cls] token和图像对应的[cls] token作哈密顿积,最后文本[cls]token形式化任务 文…

Taro 扩展 API 深度解析与实战指南

Taro 扩展 API 深度解析与实战指南 Taro 作为一款优秀的多端开发框架,提供了一系列强大的扩展 API,这些 API 极大地提升了开发效率和应用的可维护性。本文将深入解析 Taro 的扩展 API,并根据其功能特性进行分类讲解,帮助开发者更…

容器之王--Docker的部署及基本操作演练

1.2 部署docker 1.2.1 容器工作方法1.2.2 部署第一个容器 官方站点:https://docs.docker.com/ 1.2.2.1 配置软件仓库 ]# cd /etc/yum.repos.d ]# vim docker.repo [docker] name docker-ce baseurl https://mirrors.aliyun.com/docker-ce/linux/rhel/9/x86_64/sta…

VFTO与局部放电-高压设备绝缘系统的双重挑战与防护策略

目录 引言VFTO的定义与形成机理VFTO对高压设备绝缘系统的影响局部放电的危害与机制VFTO与局部放电的关联性分析检测与监测技术防护与抑制措施未来技术发展趋势结论与展望引言 在现代电力系统中,超快速暂态过电压(Very Fast Transient Overvoltage, VFTO&…

Windows下Rust编码实现MP4点播服务器

Rust编码可以实现众多简洁、可靠、高效的应用,但语法逻辑要求严格,尤其是依赖库的选择调用,需要耐心坚持“推敲”。借助DeepSeek并反复编程调试和问答改进,可以最终得到完整有效的Rust编码。下面分享Windows下Rust编码实现MP4点播…

ubuntu-相关指令

1、串口1.1确认在系统中检查设备是否正常加载,在终端输入以下命令:way1:ll /dev | grep ttyUSB(ll是LL的小写) way2:ll /dev | grep ttyACM way3:ll /dev | grep ttyCH343USB&#…

docker容器临时文件去除,服务器容量空间

概述: 接到告警提醒,服务器容量不足,去查看了一下,发现确实100g左右容量已基本用完;分析: 1)查看根目录下哪些文件夹占用容量较大 使用命令“ du -ah --max-depth1 / ” 查看目标目录下所有文件…

损耗对信号质量的影响

损耗通常分为介质损耗与导体损耗:介质损耗:介质被施加电场后介质内部带电粒子在外加电场的作用力下进行微小移动介质损耗与频率成正比导体损耗:导体由于存在电阻,在有电流流过时产生的热量造成的损耗为导体损耗。同时,…

【42】【OpenCV C++】 计算图像某一列像素方差 或 某一行像素的方差;

文章目录1 要使用到的函数 和 原理1.1 cv::meanStdDev 函数详解——计算均值和标准差1 .2 方差的通俗解释2 代码实现3 问题3.1 入口参数const cv::Mat& img 和 const cv::Mat img区别项目要求:C OPenCV 中 图像img ,当 string ROIdirection “H”时,…

元图 CAD 插件化革命:突破效率瓶颈,重构智能协作新范式

在建筑、机械、机电等工程领域,传统CAD软件的功能固化与场景割裂已成为效率提升的瓶颈。设计师常面临“通用工具难适配专业需求”、“跨平台协作效率低下”、“数据孤岛阻碍创新”等痛点。元图CAD凭借“场景插件化“核心技术,以模块化能力突破行业桎梏&a…

T:归并排序

归并排序.逆序对简介.归并排序.习题.逆序对简介 \;\;\;\;\;\;\;\;简单介绍一下归并排序的原理&#xff0c;逆序对的基本概念&#xff0c;然后收集相关的练习。 直接用一个基础问题来引入。 因此知道了: \;\;\;\;\;\;\;\;逆序对就是一对数满足 i<j&&nums[i]>nu…

三极管三种基本放大电路:共射、共集、共基放大电路

文章目录一、共集放大电路1.静态分析2.动态分析二、共基放大电路1.静态分析2.动态分析总结如何判断共射、共集、共基放大电路&#xff1f; 电路的输入回路与输出回路以发射极为公共端的电路称为共射放大电路。 电路的输入回路与输出回路以集电极为公共端的电路称为共集放大电路…

Function AI 助力用户自主开发 MCP 服务,一键上云高效部署

作者&#xff1a;靖苏 在 AI 与云原生协同创新的浪潮下&#xff0c;多模型、多场景智能应用日益普及。开发者面临的首要挑战&#xff0c;是如何实现模型之间、服务之间的高效协同&#xff0c;以及如何便捷地将自主研发能力拓展到云端&#xff0c;形成灵活可扩展的智能服务。MC…

c++编译环境安装(gcc、cmake)

一、gcc下载 下载地址&#xff1a;https://ftp.gnu.org/gnu/gcc/ 选择想要下载的版本&#xff0c;然后解压&#xff0c;查看 contrib/download_prerequisites 中的依赖。 以我下载的 gcc-7.3.0 为例&#xff0c; 二、安装依赖包 【gmp】 https://ftp.gnu.org/gnu/gmp/ 【is…

基于贝叶斯的营销组合模型实战案例(PyMC实践)

文章出自&#xff1a;基于营销预算优化的媒体投入分配研究 本篇技术亮点在于结合了广告饱和度和累积效应&#xff0c;通过数学模型和数值优化方法&#xff0c;精确计算电视与数字媒体的最佳预算分配比例&#xff0c;实现增量销售最大化。该方法适合有多渠道广告投放需求、预算…

react_05create-react-app脚手架详细解析(export)

脚手架是什么&#xff1f; 是一种工具:快速生成项目的工程化结构&#xff0c;让项目从搭建到开发&#xff0c;到部署&#xff0c;整个流程变得快速和便捷。 安装过程: 1.安装node,安装完成后验证版本,出现对应版本就表示成功 node --version npm --version2.React脚手架默认是使…

Uncaught TypeError: Illegal invocation

报错信息Uncaught TypeError: Illegal invocation关键代码$.operate.post(prefix "/edit", { "taskId": taskId, "taskStatus": completed });<input id"taskId" style"display: none;">[[${completeTask.taskId}]]&…

深入解析Go设计模式:责任链模式实战

什么是责任链模式? 责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它通过构建处理者链来传递请求。每个处理者既能自行决定是否处理当前请求,也可将请求转交给后续处理者。该模式的核心优势在于解耦请求发送方与处理方,使多个对象都能获得处理请求的机…

机器视觉系统工业相机的成像原理及如何选型

机器视觉系统是一种模拟人类视觉功能&#xff0c;通过光学装置和非接触式传感器获取图像数据&#xff0c;并进行分析和处理&#xff0c;以实现对目标物体的识别、测量、检测和定位等功能的智能化系统。其目的是让机器能够理解和解释视觉信息&#xff0c;从而做出决策或执行任务…