(三)行为模式:12、访问者模式(Visitor Pattern)(C++示例)

目录

1、访问者模式含义

2、访问者模式的UML图学习

3、访问者模式的应用场景

4、访问者模式的优缺点

5、访问者模式C++实现的实例


1、访问者模式含义

        访问者模式(Visitor Pattern)是一种行为型设计模式,它允许将一个作用于某对象结构中的各元素的操作分离出来,封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式。

        该模式的核心思想是操作分离,通过定义一个外部访问者类来扩展复杂对象结构的功能,将数据结构与数据操作解耦,使得操作可以独立于对象的类来定义。

2、访问者模式的UML图学习

访问者模式的UML类图通常包含以下角色:

(1)抽象访问者(Visitor):声明了一个或者多个访问操作,形成所有的具体元素角色必须实现的接口。

(2)具体访问者(ConcreteVisitor):实现抽象访问者角色所声明的接口,也就是抽象访问者所声明的各个访问操作。

(3)抽象节点(Element):声明一个接受操作,接受一个访问者对象作为一个参量。

(4)具体节点(ConcreteNode):实现了抽象节点所规定的接受操作。

(5)结构对象(ObjectStructure):可以遍历结构中的所有元素;如果需要,提供一个高层次的接口让访问者对象可以访问每一个元素;如果需要,可以设计成一个复合对象或者一个聚集,如列(List)或集合(Set)。

3、访问者模式的应用场景

(1)数据结构稳定的场景:数据结构(如对象结构)相对稳定,但经常需要对其上的元素执行不同的操作时,访问者模式非常有用。

(2)需要多种不同操作而不希望修改元素类的场景:如果你有多个不同的操作需要应用到同一组元素上,且不希望在元素类中添加这些操作,访问者模式可以提供一种解决方案。

(3)需要跨不同类层次结构进行操作的场景:当需要在多个不相关的类层次结构上执行操作时,访问者模式可以将操作与类层次结构分离。

(4)需要在对象结构中执行复杂计算的场景:访问者模式可以用于在对象结构中执行复杂的计算或逻辑,而不需要修改元素类本身。

4、访问者模式的优缺点

(1)优点:

  • 符合单一职责原则:访问者模式将元素操作封装在访问者类中,使得元素类专注于其核心职责,而不需要关心如何处理不同的操作。
  • 优秀的扩展性:通过添加新的访问者类,可以很容易地扩展对象结构的功能,而不需要修改元素类。
  • 聚合关系:访问者模式使得元素和访问者之间形成了一种聚合关系,从而提高了系统的灵活性和可维护性。
  • 具体元素变更不频繁:如果元素类比较稳定,即不易发生变更,那么访问者模式将非常适用。

(2)缺点

  • 增加具体元素和访问者类的难度:每次在元素结构中增加新的元素类时,都需要修改访问者类,这违反了开闭原则。
  • 破坏封装:访问者模式需要访问元素类的内部数据和方法,这可能会破坏元素的封装性。
  • 具体元素变更困难:如果元素类经常发生变更,那么访问者模式将变得难以维护,因为每次变更都需要修改访问者类。

5、访问者模式C++实现的实例

#include <iostream>
#include <vector>// 元素接口
class Element {
public:virtual void accept(class Visitor* visitor) = 0;virtual ~Element() {}
};// 具体元素A
class ConcreteElementA : public Element {
public:void accept(Visitor* visitor) override {visitor->visitConcreteElementA(this);}void operationA() {std::cout << "ConcreteElementA's operationA" << std::endl;}
};// 具体元素B
class ConcreteElementB : public Element {
public:void accept(Visitor* visitor) override {visitor->visitConcreteElementB(this);}void operationB() {std::cout << "ConcreteElementB's operationB" << std::endl;}
};// 访问者接口
class Visitor {
public:virtual void visitConcreteElementA(ConcreteElementA* element) = 0;virtual void visitConcreteElementB(ConcreteElementB* element) = 0;virtual ~Visitor() {}
};// 具体访问者
class ConcreteVisitor : public Visitor {
public:void visitConcreteElementA(ConcreteElementA* element) override {std::cout << "ConcreteVisitor visiting ConcreteElementA" << std::endl;element->operationA();}void visitConcreteElementB(ConcreteElementB* element) override {std::cout << "ConcreteVisitor visiting ConcreteElementB" << std::endl;element->operationB();}
};// 对象结构
class ObjectStructure {
private:std::vector<Element*> elements;
public:void addElement(Element* element) {elements.push_back(element);}void accept(Visitor* visitor) {for (Element* element : elements) {element->accept(visitor);}}
};int main() {ObjectStructure os;os.addElement(new ConcreteElementA());os.addElement(new ConcreteElementB());ConcreteVisitor visitor;os.accept(&visitor);// 清理内存(在实际应用中,应使用智能指针等机制来管理内存)// 这里为了简单起见,没有包含清理代码return 0;
}

在这个实例中,Element 是元素接口,ConcreteElementA 和 ConcreteElementB 是具体元素类。Visitor 是访问者接口,ConcreteVisitor 是具体访问者类。ObjectStructure 是对象结构,它包含多个元素,并允许访问者访问这些元素。在 main 函数中,我们创建了一个对象结构,添加了一些元素,并使用访问者来访问这些元素。

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

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

相关文章

windows安卓子系统wsa隐藏应用列表的安装激活使用

Windows 11 安卓子系统应用部署全攻略 windows安卓子系统wsa隐藏应用列表的安装激活使用|过检测核心前端 在 Windows 11 系统中&#xff0c;安卓子系统为用户带来了在电脑上运行安卓应用的便利。经过一系列的操作&#xff0c;我们已经完成了 Windows 11 安卓子系统的底层和前端…

Elasticsearch 集群搭建

一、集群规划 1.1 节点角色规划 节点类型配置要求推荐数量Master节点低磁盘、中等CPU/内存3&#xff08;奇数防止脑裂&#xff09;Data节点高磁盘、高内存、多核CPU根据数据量扩展Coordinating节点高CPU/内存、低磁盘2&#xff08;可选&#xff09; 1.2 硬件建议 内存&…

React 响应事件

开发环境&#xff1a;Reacttsantd 使用 React 可以在 JSX 中添加 事件处理函数。其中事件处理函数为自定义函数&#xff0c;它将在响应交互&#xff08;如点击、悬停、表单输入框获得焦点等&#xff09;时触发。 学习内容 1.编写事件处理函数的不同方法 2.如何从父组件传递事件…

SQL基础入门:从CRUD到JOIN再到索引(通俗易懂版)

一、为什么需要SQL&#xff1f; 想象你在管理一个图书馆&#xff1a; 传统方法&#xff1a;手动记录每本书的位置、借阅者、归还日期SQL方法&#xff1a;用数据库系统自动管理&#xff0c;快速查询《Java编程思想》在哪个书架 SQL&#xff08;Structured Query Language&…

MINIQMT学习课程Day11

现在开始进行策略的交易买卖分析&#xff1a; 还是之前的步骤&#xff0c;打开qmt&#xff0c;选择独立交易&#xff0c; 之后使用pycharm&#xff0c;编写py文件 导入包&#xff1a; import time, datetime, traceback, sys from xtquant import xtdata from xtquant.xttr…

# 实时人脸性别与年龄识别:基于OpenCV与深度学习模型的实现

实时人脸性别与年龄识别&#xff1a;基于OpenCV与深度学习模型的实现 在当今数字化时代&#xff0c;计算机视觉技术正以前所未有的速度改变着我们的生活与工作方式。其中&#xff0c;人脸检测与分析作为计算机视觉领域的重要分支&#xff0c;已广泛应用于安防监控、智能交互、…

Python Cookbook-5.14 给字典类型增加排名功能

任务 你需要用字典存储一些键和“分数”的映射关系。你经常需要以自然顺序(即以分数的升序)访问键和分数值&#xff0c;并能够根据那个顺序检查一个键的排名。对这个问题&#xff0c;用dict 似乎不太合适。 解决方案 我们可以使用 dict 的子类&#xff0c;根据需要增加或者重…

十四种逻辑器件综合对比——《器件手册--逻辑器件》

目录 逻辑器件 简述 按功能分类 按工艺分类 按电平分类 特殊功能逻辑器件 应用领域 详尽阐述 1 逻辑门 一、基本概念 二、主要类型 三、实现方式 四、应用领域 2 反相器 工作原理 基本功能 主要应用 常见类型 特点 未来发展趋势 3 锁存器 基本概念 工作原理 主要类型…

如何更改wsl2中的ubuntu默认安装位置

先前的一篇文章提到了如何更改wsl里面ubuntu的home目录&#xff0c;wsl装ubuntu的home目录在哪&#xff0c;如何更改home&#xff1f;_wsl安装的ubuntu在哪里-CSDN博客 这次是要更改wsl中ubuntu的安装目录&#xff0c;毕竟默认安装到c盘下会占用不少空间的。 从微软商店get后…

最近在工作中感受到了设计模式的重要性

之前了解设计模式&#xff1a;只是应付一下面试 在之前一年多的工作中也没遇到使用场景 最近在搭建验证环境的时候&#xff0c;才发现这玩意这么重要 首先是设计模式的使用场景一定是在很复杂繁琐的场景下进行的 之所以说是复杂/繁琐的场景&#xff0c;因为一些场景也许逻辑不难…

Python深度学习基础——卷积神经网络(CNN)(PyTorch)

CNN原理 从DNN到CNN 卷积层与汇聚 深度神经网络DNN中&#xff0c;相邻层的所有神经元之间都有连接&#xff0c;这叫全连接&#xff1b;卷积神经网络 CNN 中&#xff0c;新增了卷积层&#xff08;Convolution&#xff09;与汇聚&#xff08;Pooling&#xff09;。DNN 的全连接…

Linux 第三讲 --- 基础指令(三)

前言&#xff1a; 在前面我们已经讲了有十几个Linux的基础指令&#xff0c;今天我们再补充几个常用的基础指令&#xff0c;为后面的学习做准备 。 目录 前言&#xff1a; 一、两个与时间相关的指令 1.date指令 演示 &#xff1a; 时间戳 设置时间 2、cal指令 演示&#x…

基于SiamFC的红外目标跟踪

基于SiamFC的红外目标跟踪 1,背景与原理2,SiamFC跟踪方法概述2.1 核心思想2.2 算法优势3,基于SiamFC的红外跟踪代码详解3.1 网络定义与交叉相关模块3.2 SiamFC 跟踪器实现3.3 主程序:利用 OpenCV 实现视频跟踪4,总结与展望在红外监控、无人机防御以及低光照场景中,红外图…

Odoo 部署本地 把現時的excel計算表格部署上odoo 教程

要将现有的 Excel 计算表格部署到 Odoo 平台上&#xff0c;您可以按照以下步骤进行操作&#xff1a; 将 Excel 表格中的数据转移到 Odoo 模块中&#xff1a;首先&#xff0c;您需要将 Excel 表格中的数据导出为 CSV 格式&#xff0c;然后可以使用 Odoo 的数据导入功能将这些数据…

KWDB创作者计划—KWDB认知引擎:数据流动架构与时空感知计算的范式突破

引言&#xff1a;数据智能的第三范式 在数字化转型进入深水区的2025年&#xff0c;企业数据系统正面临三重悖论&#xff1a;数据规模指数级增长与实时决策需求之间的矛盾、多模态数据孤岛与业务连续性要求之间的冲突、静态存储范式与动态场景适配之间的鸿沟。KWDB&#xff08;K…

C语言 数据结构 【栈】动态模拟实现

引言 动态模拟实现栈的各个接口 一、栈的概念与结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;LastInFirstOut…

Python itertools模块的groupby函数介绍

itertools.groupby 是 Python 标准库 itertools 模块中的一个函数&#xff0c;它的主要功能是对可迭代对象中相邻的相同元素进行分组。 itertools.groupby(iterable, keyNone) 函数 作用&#xff1a; 将连续的&#xff08;相邻的&#xff09;相同元素分组&#xff0c;返回 (…

Python实例题:使用Python生成分形图片

目录 Python实例题 题目 题目分析 需求理解 关键知识点 实现思路分析 代码实现 代码解释 mandelbrot 函数&#xff1a; 设置复平面区域和图像参数&#xff1a; 计算分形数据&#xff1a; 绘图展示&#xff1a; 运行思路 Python实例题 题目 使用Python生成分形图…

系统编程1(进程的概念与原理)

进程的概念与原理 计算机组成部分一般遵循冯诺依曼结构&#xff0c;也就是由控制器、运算器、存储器、输入设备、输出设备五个部分组成。 ⦁ 程序的编译 一般在编写出程序之后&#xff0c;并不能直接运行&#xff0c;而是需要把程序通过编译器进行编译&#xff0c;生成可执行…

《Vue Router实战教程》5.嵌套路由

欢迎观看《Vue Router 实战&#xff08;第4版&#xff09;》视频课程 嵌套路由 一些应用程序的 UI 由多层嵌套的组件组成。在这种情况下&#xff0c;URL 的片段通常对应于特定的嵌套组件结构&#xff0c;例如&#xff1a; 通过 Vue Router&#xff0c;你可以使用嵌套路由配置…