当前位置: 首页 > news >正文

设计模式——模板模式

定义与基本概念

  • 模板模式(Template Pattern)是一种行为设计模式。它在一个抽象类中定义了一个操作的算法骨架,将一些步骤的实现延迟到具体子类中。这个抽象类就像是一个模板,定义了执行某个流程的基本框架,而具体的细节可以由不同的子类根据自身的需求来填充。
  • 例如,在制作饮品的过程中,制作饮品的流程(如准备材料、混合材料、添加调料、包装等)可以看作是一个模板。不同的饮品(如咖啡、茶)在这个流程的某些具体步骤(如混合材料、添加调料)上会有不同的做法,但整体的流程框架是相似的。

结构组成

  • 抽象模板(Abstract Template)类:
    它定义了一个或多个抽象方法,这些方法代表了算法中的某些步骤,其具体实现将由具体子类完成。同时,抽象模板类还定义了一个模板方法(Template Method),这个方法规定了算法的骨架,它按照一定的顺序调用其他方法(包括抽象方法和具体方法)。以饮品制作的例子来说,抽象模板类可能定义了prepare()(抽象方法,准备材料)、mix()(抽象方法,混合材料)、addSeasoning()(抽象方法,添加调料)、package()(具体方法,包装)和makeDrink()(模板方法)。makeDrink()方法的实现可能是按照准备材料、混合材料、添加调料、包装的顺序调用其他方法。
  • 具体模板(Concrete Template)类:
    继承自抽象模板类,实现了抽象模板类中的抽象方法。每个具体模板类代表了一种具体的实现方式,根据不同的业务需求来填充抽象方法的具体内容。在饮品制作的例子中,Coffee类和Tea类是具体模板类,Coffee类的prepare()方法可能是准备咖啡豆和水,mix()方法可能是研磨咖啡豆后煮咖啡,addSeasoning()方法可能是加糖和奶;而Tea类的prepare()方法可能是准备茶叶和水,mix()方法可能是泡茶,addSeasoning()方法可能是加柠檬片。

工作原理

  • 客户端代码创建具体模板类的对象,然后调用抽象模板类中定义的模板方法。模板方法在执行过程中,会按照预先定义的顺序调用其他方法,其中抽象方法的具体实现由具体模板类提供。这样,不同的具体模板类就可以在遵循相同算法骨架的基础上,实现不同的具体行为。
  • 例如,在一个数据处理系统中,有一个抽象的数据处理模板类,它定义了loadData()(抽象方法)、processData()(抽象方法)、saveData()(具体方法)和execute()(模板方法)。execute()方法按照先loadData(),再processData(),最后saveData()的顺序调用其他方法。具体的数据处理子类(如TextDataProcessor和ImageDataProcessor)实现了loadData()和processData()方法,以适应不同类型数据的处理方式。当客户端代码调用TextDataProcessor对象的execute()方法时,就会按照TextDataProcessor类实现的loadData()和processData()方法以及DataProcessor类(抽象模板类)定义的saveData()方法来完成文本数据的处理流程。

代码示例

以下是一个简单的 C++ 模板模式示例,以文件处理为例。

  • 首先是抽象模板类:
class FileHandler {
public:void processFile() {openFile();readFile();processContents();closeFile();}virtual void openFile() = 0;virtual void readFile() = 0;virtual void processContents() = 0;void closeFile() {std::cout << "文件已关闭。" << std::endl;}
};
  • 然后是具体模板类,以文本文件处理为例:
class TextFileHandler : public FileHandler {
public:void openFile() override {std::cout << "打开文本文件。" << std::endl;}void readFile() override {std::cout << "读取文本文件内容。" << std::endl;}void processContents() override {std::cout << "处理文本文件内容。" << std::endl;}
};
  • 另一个具体模板类,以二进制文件处理为例:
class BinaryFileHandler : public FileHandler {
public:void openFile() override {std::cout << "打开二进制文件。" << std::endl;}void readFile() override {std::cout << "读取二进制文件内容。" << std::endl;}void processContents() override {std::cout << "处理二进制文件内容。" << std::endl;}
};
  • 使用示例:
int main() {TextFileHandler textHandler;textHandler.processFile();std::cout << "------------------------" << std::endl;BinaryFileHandler binaryHandler;binaryHandler.processFile();return 0;
}

优点

  • 代码复用性高:
    抽象模板类定义的算法骨架可以被多个具体子类复用。在上述文件处理的例子中,processFile()方法的流程(打开文件、读取文件、处理内容、关闭文件)在文本文件处理和二进制文件处理中都可以使用,减少了代码的重复编写。
  • 可维护性好:
    由于算法的骨架和具体步骤的实现分离,当需要修改算法的整体流程时,只需要在抽象模板类中修改模板方法;当需要修改某个具体步骤的实现时,只需要在相应的具体子类中进行修改。例如,在一个软件系统的用户注册流程中,如果需要修改注册的整体流程(如增加验证步骤),可以在抽象的注册模板类中修改模板方法;如果需要修改某个验证方式(如密码验证),可以在具体的注册子类中修改相应的抽象方法的实现。
  • 符合开闭原则:
    可以很容易地通过创建新的具体子类来扩展系统的功能,而不需要修改已有的代码。比如,在文件处理系统中,如果要增加一种新的文件类型(如 XML 文件)的处理,只需要创建一个新的XMLFileHandler类,实现抽象模板类中的抽象方法即可。

缺点

  • 可能导致类层次复杂:
    如果有多个抽象方法需要具体子类实现,并且具体子类的数量较多,会导致类层次结构变得复杂。例如,在一个复杂的工作流系统中,每个工作流步骤都可能有多个抽象方法需要具体子类实现,随着工作流类型的增加,类的数量和层次结构会变得难以管理。
  • 子类的灵活性有限:
    具体子类必须遵循抽象模板类定义的算法骨架,这在一定程度上限制了子类的灵活性。如果某个具体子类需要对算法骨架进行较大的修改,可能需要重新设计整个类结构,或者采用其他设计模式来解决。

相关文章:

设计模式——模板模式

定义与基本概念 模板模式&#xff08;Template Pattern&#xff09;是一种行为设计模式。它在一个抽象类中定义了一个操作的算法骨架&#xff0c;将一些步骤的实现延迟到具体子类中。这个抽象类就像是一个模板&#xff0c;定义了执行某个流程的基本框架&#xff0c;而具体的细…...

CV22_语义分割基础

1. 常见的分割类型 在计算机视觉领域&#xff0c;根据不同的应用场景和需求&#xff0c;分割任务可以分为几种主要类型。以下是几种常见的分割类型&#xff1a; 语义分割&#xff08;Semantic Segmentation&#xff09;&#xff1a; 语义分割的目标是将图像中的每个像素分配到…...

Dubbo源码解析-Dubbo的线程模型(九)

一、Dubbo线程模型 首先明确一个基本概念&#xff1a;IO 线程和业务线程的区别 IO 线程&#xff1a;配置在netty 连接点的用于处理网络数据的线程&#xff0c;主要处理编解码等直接与网络数据 打交道的事件。 业务线程&#xff1a;用于处理具体业务逻辑的线程&#xff0c;可以…...

【Canvas与标志】圆角三角形生化危险警示标志

【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>圆角三角形生化危险警示标志 Draft1</title><style type&qu…...

解决Dcat Admin laravel框架登录报错问题,(blocked:mixed-content)

前言 在使用 Dcat Admin 后台登录时&#xff0c;发生 error 报错&#xff1a;(blocked:mixed-content) xhr VM484:1&#xff0c;浏览器拦截 其实这是浏览器在 HTTPS 页面中尝试加载 HTTP 资源&#xff0c;导致浏览器阻止了这些不安全的请求。 解决 在 .env 文件中添加或修改 AD…...

(三)Sping Boot学习——升级jdk1.8-jdk18

1.修改系统环境变量。 2.idea中修改配置。 3.项目setting中设置修改 4.更新后还要重新下载依赖mvn clean install &#xff0c;并且记住reload 项目。同时查看java -version查看一下jdk版本。...

语言模型中的多模态链式推理

神经网络的公式推导 简介摘要引言多模态思维链推理的挑战多模态CoT框架多模态CoT模型架构细节编码模块融合模块解码模块 实验结果运行代码补充细节安装包下载Flan-T5数据集准备rougenltkall-MiniLM-L6-v2运行 简介 本文主要对2023一篇论文《Multimodal Chain-of-Thought Reason…...

SCons:下一代构建工具,如何用 Python 驱动高效构建?

在现代软件开发中&#xff0c;构建工具是开发流程中不可或缺的一环。无论是小型项目还是跨平台的复杂工程&#xff0c;选择一个高效、灵活的工具都能显著提高开发效率和代码质量。SCons&#xff0c;一个以 Python 为基础的构建工具&#xff0c;通过自动化依赖管理、灵活的扩展性…...

springboot 整合 rabbitMQ (延迟队列)

前言&#xff1a; 延迟队列是一个内部有序的数据结构&#xff0c;其主要功能体现在其延时特性上。这种队列存储的元素都设定了特定的处理时间&#xff0c;意味着它们需要在规定的时间点或者延迟之后才能被取出并进行相应的处理。简而言之&#xff0c;延时队列被设计用于存放那…...

ES 基本使用与二次封装

概述 基本了解 Elasticsearch 是一个开源的分布式搜索和分析引擎&#xff0c;基于 Apache Lucene 构建。它提供了对海量数据的快速全文搜索、结构化搜索和分析功能&#xff0c;是目前流行的大数据处理工具之一。主要特点即高效搜索、分布式存储、拓展性强 核心功能 全文搜索:…...

分割一切2.0,SAM2详解

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;编程探索专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年11月24日20点03分 神秘男子影, 秘而不宣藏。 泣意深不见, 男子自持重, 子夜独自沉。 论文链接 点击开启你的论文编程之旅…...

Spring AI Fluent API:与AI模型通信的流畅体验

引言 随着人工智能&#xff08;AI&#xff09;技术的飞速发展&#xff0c;越来越多的应用场景开始融入AI技术以提升用户体验和系统效率。在Java开发中&#xff0c;与AI模型通信成为了一个重要而常见的需求。为了满足这一需求&#xff0c;Spring AI引入了ChatClient&#xff0c…...

基于python的长津湖评论数据分析与可视化,使用是svm情感分析建模

引言 研究背景及意义 上世纪初开始&#xff0c;中国电影就以自己独有的姿态登上了世界电影史的舞台。中国电影作为国家文化和思想观念的反映与延伸&#xff0c;能够增强文化自信&#xff0c;在文化输出方面有着极其重要的作用1[1]。 改革开放以来&#xff0c;随着生产力的提高…...

Lucene(2):Springboot整合全文检索引擎TermInSetQuery应用实例附源码

前言 本章代码已分享至Gitee: https://gitee.com/lengcz/springbootlucene01 接上文。Lucene(1):Springboot整合全文检索引擎Lucene常规入门附源码 如何在指定范围内查询。从lucene 7 开始&#xff0c;filter 被弃用&#xff0c;导致无法进行调节过滤。 TermInSetQuery 指定…...

shell完结

声明&#xff01; 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&a…...

【2024最新】基于Springboot+Vue的智慧食堂系统Lw+PPT

作者&#xff1a;计算机搬砖家 开发技术&#xff1a;SpringBoot、php、Python、小程序、SSM、Vue、MySQL、JSP、ElementUI等&#xff0c;“文末源码”。 专栏推荐&#xff1a;SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;Java精选实战项…...

NVR小程序接入平台EasyNVR多品牌NVR管理工具:高效管理分散视频资源的解决方案

在当今数字化、智能化的时代背景下&#xff0c;视频监控已成为各行各业不可或缺的一部分&#xff0c;从公共安全到企业运维&#xff0c;再到智慧城市建设&#xff0c;视频资源的管理与应用正面临着前所未有的挑战。如何高效整合、管理这些遍布各地的分散视频资源&#xff0c;成…...

排序算法(三)--插入排序

文章目录 一、插入排序的基本原理二、插入排序的C语言实现三、代码解析 插入排序 C语言实例 一、插入排序的基本原理 插入排序的基本思想是将数组中的元素逐一取出&#xff0c;然后将其插入到已经排好序的部分中的适当位置&#xff0c;直到整个数组排序完成。具体步骤如下&…...

YOLOv11融合[ECCV 2018]RCAN中的RCAB模块及相关改进思路

YOLOv11v10v8使用教程&#xff1a; YOLOv11入门到入土使用教程 YOLOv11改进汇总贴&#xff1a;YOLOv11及自研模型更新汇总 《Image Super-Resolution Using Very Deep Residual Channel Attention Networks》 一、 模块介绍 论文链接&#xff1a;https://arxiv.org/abs/1807…...

排序(Java数据结构)

1. 排序的概念及引用 1.1 排序的概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。(所有的排序都是默认从小到大排序) 稳定性&#xff1a;假定在待排序的记录序列中&#xff…...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写&#xff0c;中文译为后进先出。这是一种数据结构的工作原则&#xff0c;类似于一摞盘子或一叠书本&#xff1a; 最后放进去的元素最先出来 -想象往筒状容器里放盘子&#xff1a; &#xff08;1&#xff09;你放进的最后一个盘子&#xff08…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

C++.OpenGL (10/64)基础光照(Basic Lighting)

基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计

随着大语言模型&#xff08;LLM&#xff09;参数规模的增长&#xff0c;推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长&#xff0c;而KV缓存的内存消耗可能高达数十GB&#xff08;例如Llama2-7B处理100K token时需50GB内存&a…...