2023-7-20-第二十一式访问者模式

news2024/11/24 4:12:16


🍿*★,°*:.☆( ̄▽ ̄)/$:*.°★* 🍿

💥💥💥欢迎来到🤞汤姆🤞的csdn博文💥💥💥
💟💟喜欢的朋友可以关注一下,下次更新不迷路💟💟
😆😆😆私聊获取个人订阅号哦,欢迎订阅共同学习😆😆😆
💖💖💖💖可以加入大家庭群聊,一起学习天天有福利💖💖💖💖





🍬本文摘要

在这里插入图片描述

设计方法二十三式之访问者模式


目录

  • 🍬本文摘要
  • 😉一、基础概念
  • 🐱‍🐉二、访问者模式实现
  • 🎉三、模块之间的关系
  • 🐱‍🚀四、注意事项
  • 🎂五、使用场景
  • 🍳参考文献
  • 🧊文章总结



😉一、基础概念

访问者模式(Visitor Pattern)是一种行为型设计模式,通过将算法的操作从数据结构中分离出来,使得可以在不改变数据结构的情况下定义新的操作。该模式允许您对一组对象执行特定操作,而无需修改这些对象的类。

在访问者模式中,有两个主要角色:

  1. 访问者(Visitor):定义了对各种元素对象的操作方法,每个操作都可以根据具体的元素类型执行不同的逻辑。
  2. 元素(Element):表示被访问的对象,提供一个接受访问者的方法,该方法将调用访问者的适当操作。

访问者模式的核心思想是将操作和数据结构分离,以便于增加新的操作而无需修改现有的数据结构。这种模式适用于当对数据结构进行的操作需要改变时,但是数据结构本身却保持稳定。

使用访问者模式的主要优点包括:

  • 可以增加新的操作,而无需修改现有的元素类。
  • 将相关的操作集中在访问者类中,使代码更易维护和理解。
  • 可以对数据结构进行复杂的操纵,而无需在元素类中添加大量的方法。

然而,访问者模式也有一些缺点,例如:

  • 增加新的元素类比较困难,因为每个访问者类都必须与所有的元素类进行交互。
  • 可能会破坏封装性,因为访问者需要访问元素的内部状态。

总之,访问者模式提供了一种遍历数据结构并对其执行操作的灵活方式。它可以帮助我们将操作与数据结构解耦,并使代码更易于扩展和维护。


🐱‍🐉二、访问者模式实现

在C++中,可以使用访问者模式来实现对一组对象执行特定操作的场景。下面是一个简单的示例:

#include <iostream>
#include <vector>

// 前向声明 ElementA 和 ElementB 类
class ElementA;
class ElementB;

// 定义 Visitor 抽象基类
class Visitor {
public:
    virtual void visit(ElementA* element) = 0;
    virtual void visit(ElementB* element) = 0;
};

// 定义 Element 抽象基类
class Element {
public:
    virtual void accept(Visitor* visitor) = 0;
};

// 具体元素类 ElementA
class ElementA : public Element {
public:
    void accept(Visitor* visitor) override {
        visitor->visit(this);
    }

    void operationA() {
        std::cout << "Performing operation A on ElementA" << std::endl;
    }
};

// 具体元素类 ElementB
class ElementB : public Element {
public:
    void accept(Visitor* visitor) override {
        visitor->visit(this);
    }

    void operationB() {
        std::cout << "Performing operation B on ElementB" << std::endl;
    }
};

// 具体的访问者类 ConcreteVisitor
class ConcreteVisitor : public Visitor {
public:
    void visit(ElementA* element) override {
        element->operationA();
    }

    void visit(ElementB* element) override {
        element->operationB();
    }
};

int main() {
    // 创建具体元素对象
    ElementA elementA;
    ElementB elementB;

    // 创建访问者对象
    ConcreteVisitor concreteVisitor;

    // 使用访问者访问元素对象
    elementA.accept(&concreteVisitor);
    elementB.accept(&concreteVisitor);

    return 0;
}

在这个示例中,我们定义了Visitor抽象基类和具体的访问者类ConcreteVisitor。同时,定义了Element抽象基类和具体元素类ElementAElementB。元素类通过实现accept()方法来接受访问者的访问。

当访问者访问元素时,元素会将自身作为参数传递给访问者的对应方法。访问者根据元素的类型执行相应的操作。在示例中,ConcreteVisitorvisit()方法分别执行了ElementAElementB的特定操作。

在主函数中,我们创建了具体的元素对象,并创建了具体的访问者对象。然后使用访问者对象访问元素对象,从而触发相应的操作。

运行此示例会输出以下内容:

Performing operation A on ElementA
Performing operation B on ElementB

这表明访问者模式成功地将特定操作与元素对象解耦,并通过访问者对象来执行操作。


🎉三、模块之间的关系

在访问者模式中,有多个关键组件之间的关系。下面是各个组件之间的关系说明:

  1. Visitor(访问者):访问者是一个抽象基类或接口,定义了一组访问操作方法,每个方法对应于元素类中的一种具体操作。访问者可以通过这些方法访问和处理不同类型的元素对象。

  2. ConcreteVisitor(具体访问者):具体访问者是 Visitor 的实现类,它实现了 Visitor 定义的所有访问操作方法。每个具体访问者类负责执行特定的操作逻辑。

  3. Element(元素):元素是一个抽象基类或接口,定义了一个 accept() 方法,该方法接收一个访问者对象作为参数,并在其中调用访问者的对应方法。元素类将自身作为参数传递给访问者的方法,以便访问者可以对其进行操作。

  4. ConcreteElement(具体元素):具体元素是 Element 的实现类,它实现了 Element 定义的 accept() 方法,并根据需要提供其他操作方法。具体元素类通过实现 accept() 方法,将自身传递给访问者对象进行访问。

  5. ObjectStructure(对象结构):对象结构是一个包含元素对象集合的类或数据结构。它提供了一种管理元素对象的方式,并且允许访问者遍历整个集合并对其中的元素进行操作。

在访问者模式中,元素对象通过接受访问者对象来实现特定操作的分离。当需要对元素执行特定操作时,访问者对象可以通过元素的 accept() 方法访问和操作元素,从而实现了解耦和灵活性。

总结起来,访问者模式的关系如下:

Visitor <|-- ConcreteVisitor
Element <|-- ConcreteElement
           ConcreteElement -- accept(Visitor)
ObjectStructure <-- Element
ConcreteElement -- performOperation()

🐱‍🚀四、注意事项

使用访问者模式时,有几个注意事项需要考虑:

  1. 增加新的元素类困难:在访问者模式中,如果需要添加新的元素类,则需要修改访问者接口和所有具体访问者的实现。这是因为每个具体访问者都需要与所有元素类进行交互。如果经常需要添加新的元素类,这可能导致代码维护方面的困难。

  2. 破坏封装性:访问者模式可能会破坏元素类的封装性。为了让访问者能够访问元素的内部状态,元素类可能需要暴露一些私有成员或提供访问方法。这可能会降低元素类的封装性和安全性。

  3. 影响可扩展性:当存在多个访问者并且每个访问者只对元素执行少量操作时,访问者模式可以很好地扩展。但是,如果一个访问者需要执行大量的操作,可能会导致访问者类变得臃肿,并且不易于维护和扩展。

  4. 遵循依赖倒置原则:在使用访问者模式时,应该遵循依赖倒置原则(Dependency Inversion Principle)。具体来说,元素应该依赖于抽象的访问者接口,而不是具体的访问者类。这样可以使得元素类与具体访问者解耦,提高代码的灵活性和可维护性。

  5. 合理使用访问者模式:访问者模式适用于操作(Visitor)和数据结构(Element)分离且需要频繁变化的场景。在其他情况下,如果只有少量固定的操作,或者操作与数据结构高度耦合,那么使用访问者模式可能会增加不必要的复杂性。

总之,虽然访问者模式可以提供一种灵活和可扩展的方式来处理对象结构中的元素操作,但也需要慎重考虑其适用性和使用方式,以避免不必要的复杂性和维护困难。


🎂五、使用场景

访问者模式适用于以下场景:

  1. 对象结构中的元素操作频繁变化:当一个对象结构中的元素类经常需要添加新的操作,而且这些操作可能会频繁地发生变化时,使用访问者模式可以将操作与元素类分离,使得添加新操作更加灵活和可扩展。

  2. 操作与数据结构分离:如果需要对一个对象结构中的元素执行不同的操作,并且希望将操作与元素类解耦,访问者模式提供了一种有效的方式。通过将操作定义为访问者类的方法,元素类可以接受访问者并将自身作为参数传递给访问者的方法,从而实现了操作与数据结构的分离。

  3. 集中相关操作:访问者模式可以将相关的操作集中在一个访问者类中,使得代码更易于维护和管理。如果有多个元素类需要执行相似或相关的操作,可以将这些操作放在一个访问者类中,并通过访问者来执行这些操作,而不需要在每个元素类中重复代码。

  4. 新增操作不影响元素类:如果需要为已有的元素类增加新的操作,并且不希望修改元素类的代码,则可以使用访问者模式。通过创建新的具体访问者类来实现新的操作,而不需要修改元素类的代码。

  5. 执行复杂操作:访问者模式适用于对数据结构进行复杂的操纵和处理的场景。通过将复杂的操作封装在访问者类中,可以使得元素类保持简单,而且可以按需调用访问者的方法来执行复杂的操作。

总之,访问者模式在需要对一个对象结构中的元素执行不同操作,并且希望将操作与元素类解耦的情况下,提供了一种优雅且可扩展的设计方案。


🍳参考文献

🧊文章总结

提示:这里对文章进行总结:

   本文讲了关于访问者模式的知识。






更多好文推荐

🍸2021-4月Python 机器学习——中文新闻文本标题分类
🍹2021年4月-(计算机网络)小型校园网络模拟搭建,最全最准确版
🍺2022-10-31-基于用户的协同过滤推荐算法实现+MAE+RMSE
🍻2022-11-28-大数据可视化,特征维度大于50
🥂2023-3-9-一篇简短的文章把C++左右值关系讲的透透彻彻

上一篇
End
下一篇

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

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

相关文章

unity预制体打包

unity做好的预制体如果给别的工程使用&#xff0c;如果是单纯的ctrlcv会导致丢失引用&#xff0c;如材质信息等&#xff0c;我们可以将其打包好再导入给别的工程。 如打包这个cube&#xff1a; 点击Export&#xff0c;选择保存位置

【算法基础:搜索与图论】3.2 树与图的dfs和bfs

文章目录 例题846. 树的重心&#xff08;深度优先遍历 / 树形DP&#xff09;⭐⭐⭐⭐⭐&#x1f6b9;&#x1f6b9;&#x1f6b9;&#x1f6b9;&#x1f6b9;&#xff08;重要&#xff01;好题&#xff01;&#xff09;847. 图中点的层次 相关链接 要学会建树、建图的通用方法。…

【C++】C++ 11 新特性

文章目录 &#x1f4d5; ★ 右值引用 ★概念左值引用和右值引用的比较使用场景和意义移动构造左值引用的缺陷 完美转发属性丢失为什么会属性丢失解决方法 &#x1f4d5; 新的类功能默认成员函数default 和 delete 关键字 &#x1f4d5; lambda 表达式问题的提出概念函数对象和 …

nuxt获取地址栏(路由)参数

要获取的路由地址&#xff08;页面顶部地址栏&#xff09;&#xff1a;http://172.31.0.1:5353/judge-manage?id3694089482878918764&name%E6%B5%8B%E8%AF%95&judgeIde9IJWN5usmzbrtNC3zYSRtAcKu-M333h 1、获取域名或ip端口&#xff1a;172.31.0.1:5353 2、获取地址…

JMeter的使用方法

JMeter是开源软件&#xff0c;100%的使用Java语言来进行开发的&#xff0c;支持主流的协议&#xff08;HTTP,HTTPS,WebService,gRPC&#xff09;的API测试和性能测试,是一款非常优秀的测试工具软件。 java 语言编写的程序&#xff0c;程序要运行&#xff0c;对外运行的程序有两…

Windows 2012 R2 编辑ini文本遇到的编码问题

在编辑服务端配置文件时&#xff0c;发现对于ini文本文件&#xff1a; 需注意点一&#xff1a;如果另存为UTF-8保存的实际上格式是UTF-8-BOM编码格式&#xff1b; 但是两种格式是存在差异的&#xff1a; 因此造成在使用C#调用系统DLL读取文件时并未报错&#xff0c;但是当使用…

access数据库注入

access数据库一般是100人以下的小型数据库&#xff0c;后缀是asp的网站 先加一个’看下回显内容&#xff0c;有没有报错 在用and 11 和and 12看下回复内容 and 12 有报错内容&#xff0c;可以确定存在注入点 猜数据库名字&#xff0c;asp的数据库后缀是mdb and exists(select *…

Java将数据集合转换导出为图片

将数据集合导出为图片 Java将数据集合转换导出为根据数据自适应大小的图片&#xff0c;并且保证数据的完整展示 工具类代码 package xxxxxxxxx;import cn.hutool.core.date.DateTime;import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.se…

linux部署前后端项目

使用nginx部署前端vue项目&#xff1a; nginx的安装就不在过了&#xff0c;直接打包vue项目&#xff1a; npm run build运行完之后会生成一个dist文件夹 将dist文件夹复制到linux文件中&#xff0c;我这里放到了/usr/local/vue目录下&#xff1a; 打开nginx的conf目录下的ngi…

Vue3通透教程【十六】TS编译配置

文章目录 &#x1f31f; 写在前面&#x1f31f; 初始化配置文件⭐ target⭐ module⭐ lib⭐ types/node⭐ include⭐ outDir&#x1f31f; 写在最后 &#x1f31f; 写在前面 专栏介绍&#xff1a; 凉哥作为 Vue 的忠实 粉丝输出过大量的 Vue 文章&#xff0c;应粉丝要求开始更…

muduo库的log

muduo 库里的日志打印比较复杂&#xff0c;跟标准库 std::cout << 似乎比较像吧&#xff0c;库里自己实现了“流”式的日志打印&#xff0c;今天一起来看一下。 int main(int argc, char* argv[]) {CLogger::setLogLevel(CLogger::INFO);LOG_INFO << "loggin…

Xcode 15 beta 4 (15A5195m) - Apple 平台 IDE

Xcode 15 beta 4 (15A5195m) - Apple 平台 IDE IDE for iOS/iPadOS/macOS/watchOS/tvOS/visonOS 请访问原文链接&#xff1a;https://sysin.org/blog/apple-xcode-15/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org visonOS …

07 QT信号与槽重载问题及解决

Tips&#xff1a; 参数重载时需要函数指针明确重载的是哪一个&#xff0c;避免出现二义性 案例修改&#xff1a; 重载学生类中的treat函数&#xff0c;增加foodName参数 //Teacher.h #ifndef TEACHER_H #define TEACHER_H#include <QObject>class Teacher : public QObje…

Jmeter安装及快速入门(超详细教程)

目录 1.安装Jmeter 1.1.下载 1.2.解压 1.3.运行 2.快速入门 2.1.设置中文语言 2.2.基本用法 1.安装Jmeter Jmeter依赖于JDK&#xff0c;所以必须确保当前计算机上已经安装了JDK&#xff0c;并且配置了环境变量。 1.1.下载 可以Apache Jmeter官网下载&#xff0c;地址&am…

18.matlab数据分析多项式的拟合(matlab程序)

1.简述 解决数据拟合问题最重要方法是最小二乘法和回归分析。如&#xff0c;我们需要从一组测定的数据&#xff08;例如N个点&#xff08;xi&#xff0c;yi&#xff09;&#xff08;i0,1&#xff0c;…&#xff0c;m&#xff09;&#xff09;去求得自变量 x 和因变量 y 的一个近…

解决Vue2中控制台报错 [WDS] Disconnected! 问题

Vue2 项目打开控制台时发现如下报错 &#xff1a; [WDS] Disconnected! client?9556:172 其实并没有对项目运行本身造成什么实质性的影响&#xff0c;但是一条红色的提示摆在那里确实不太好看&#xff0c;还是把他给解决掉吧。 在网上看好多人说需要将 config…

django实现好看的翻页分页效果,封装翻页组件,实现在任意页面实现翻页功能。

一、实现目标 在做web开发的时候,我们经常需要显示表格或者列表类型的数据,当数据比较多的时候,我们不会一次性全部显示出来,而是一次只显示固定数量的数据,当要查看其他数据时,点击翻页进行查看,而这个功能就是我们实现的分页、翻页功能。 话不多说,我们期望实现的翻页…

opencv-15 数字水印原理

最低有效位&#xff08;Least Significant Bit&#xff0c;LSB&#xff09;指的是一个二进制数中的第 0 位&#xff08;即最低位&#xff09;。 最低有效位信息隐藏指的是&#xff0c;将一个需要隐藏的二值图像信息嵌入载体图像的最低有效位&#xff0c;即将载体图像的最低有效…

央视报道!北京筑龙深度参编的 《企业采购供应链数字化成熟度模型》开始实施

7月12日&#xff0c;由中国物流与采购联合会牵头&#xff0c;北京筑龙深度参与编写的《企业采购供应链数字化成熟度模型》团体标准在“第四届国有企业数智化采购与智慧供应链论坛”上重磅发布。该标准于7月15日起正式实施&#xff0c;并将在企业中开展模型应用评估试点工作。 图…

服务器量化训练操作说明

Freespace服务器预训练主要步骤&#xff1a; 首先登录堡垒机&#xff0c;命令如下&#xff1a; ssh xxxrelay.baidu-int.com &#xff08;xxx为个人邮箱前缀&#xff09; 密码为个人邮箱密码 登录工作机&#xff0c;命令如下&#xff1a; ssh l3yq01-gpu-255-122-22-00.e…