设计模式之访问者模式(C++)

news/2024/4/17 3:01:57/文章来源:https://blog.csdn.net/zhaitianbao/article/details/130319735

作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

一、访问者模式是什么?

       访问者模式是一种行为型的软件设计模式,表示一个作用于某对象结构中的各元素的操作。使得在不改变各元素类的前提下,能定义作用于这些元素的操作。

       该模式适合数据结构相对稳定且算法又易变化的系统。数据结构是被访问者,算法操作相当于访问者。

       访问者模式的优点:

  1. 良好扩展性。扩展对元素的操作,只需要添加访问者。
  2. 满足单一职责原则。相关的操作封装为一个访问者,使得访问者职责单一。
  3. 解耦。数据结构自身和作用于它的操作解耦合。

       访问者模式的缺点:

  1. 不易增加元素类。每增加一个元素类,访问者的接口和实现都要进行变化。
  2. 违背了依赖倒置原则。访问者依赖的是具体元素而不是抽象元素。
  3. 破坏封装。访问者可以获取被访问元素的细节。

二、访问者模式

2.1 结构图

       客户端即Main主函数,对象结构中存放了被访问的元素集合以及遍历各个元素的方法,使得抽象访问者可以依次与具体元素对接,完成访问。

2.2 代码示例

       场景描述:市长视察学校和企业。

//Visitor.h
/****************************************************/
#pragma once
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>using namespace std;class Visitor;// 抽象元素类-地点(被访问)
class Place 
{
public:// 构造函数Place(string name) : m_name(name) {}// 接受访问virtual void accept(Visitor* visitor) = 0;// 获取名字string getName() {return m_name;}private:string m_name;
};// 具体元素类-学校
class School : public Place 
{
public:// 构造函数School(string name) : Place(name) {}// 接受访问virtual void accept(Visitor* visitor);};// 具体元素类-企业
class Enterprise : public Place 
{
public:// 构造函数Enterprise(string name) : Place(name) {}// 接受访问virtual void accept(Visitor* visitor);};// 抽象访问者
class Visitor 
{
public:// 访问学校virtual void visitSchool(School* school) = 0;// 访问企业virtual void visitEnterprise(Enterprise* enterprise) = 0;};// 具体访问者-市长
class Mayor : public Visitor 
{
public:// 访问学校virtual void visitSchool(School* school) {cout << "市长参观了:" << school->getName() << endl;cout << "对老师和学生表达了诚挚的慰问。" << endl;}// 访问企业virtual void visitEnterprise(Enterprise* enterprise) {cout << "市长参观了:" << enterprise->getName() << endl;cout << "对企业的发展表示肯定。" << endl;}};// 访问行为类
class Visiting
{
public:// 添加被访问地点void add(Place* place) {places.push_back(place);}// 删除被访问地点void remove(Place* place) {places.erase(std::remove(places.begin(), places.end(), place), places.end());}// 进行访问void accept(Visitor* visitor) {for (auto place : places) {place->accept(visitor);}}private:std::vector<Place*> places;
};
//Visitor.cpp
/****************************************************/
#include "Visitor.h"// 接受访问
void School::accept(Visitor* visitor) {visitor->visitSchool(this);
}// 接受访问
void Enterprise::accept(Visitor* visitor) {visitor->visitEnterprise(this);
}
//main.cpp
/****************************************************/
#include <iostream>
#include <string>
#include "Visitor.h"using namespace std;int main() 
{Visiting *visiting = new Visiting();Place *school = new School("东华大学");Place *enterprise = new Enterprise("华为");Visitor *mayor = new Mayor();// 添加被访问对象cout << "首日,";visiting->add(school);visiting->add(enterprise);// 安排市长进行访问visiting->accept(mayor);// 次日行程,删除某个被访问对象后再次访问cout << "次日,";visiting->remove(school);visiting->accept(mayor);// 删除delete visiting;delete school;delete enterprise;delete mayor;visiting = nullptr;school = nullptr;enterprise = nullptr;mayor = nullptr;return 0;
}

       程序结果如下。

       访问者模式使得访问操作与被访问元素解耦,同样是访问学校和企业,不同的访问者来干的事情和目的是不一样的,而这个不同的内容就可以在访问者类中实现。不过该模式不太适合增加新的元素,就像添加一个新的被访问对象-派出所,那每个访问者都要添加访问派出所的操作,违反了开闭原则。

三、总结

       我尽可能用较通俗的话语和直观的代码例程,来表述我对访问者模式的理解,或许有考虑不周到的地方,如果你有不同看法欢迎评论区交流!希望我举的例子能帮助你更好地理解访问者模式。

       如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!

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

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

相关文章

智能家居代码架构---简单工厂模式

(11条消息) 智能家居 (10) ——人脸识别祥云平台编程使用(编译libcurl库支持SSL&#xff0c;安装SSL依赖库libssl、libcrypto)openssl 依赖库行稳方能走远的博客-CSDN博客 看上面这个博客的往期文章 代码设计经验的总结&#xff0c;稳定&#xff0c;拓展性更强。一系列编程思…

DAX:概述ALL函数

简单的说&#xff0c;当ALL用作表函数时&#xff0c;忽略应用到表上的任何过滤器&#xff0c;并返回数据表&#xff1b;当ALL用作CALCULATE和CALCULATETABLE函数中修饰器时&#xff0c;ALL函数从扩展表中移除已经应用的过滤上下文。 注意自动存在(auto-eixist)对ALL()函数的影响…

选址-路径问题(Location-Routing Problem, LRP)

今天为大家介绍的是选址-路径问题(Location-Routing Problem, LRP)&#xff0c;首先上目录 目录 问题简介 基础模型、扩展问题及应用 算法 参考文献 1 问题简介 为了更好地了解这个问题&#xff0c;我们不妨当一波老板。 想象一下我们是经营一家口罩生产企业的老板&am…

案例——数据表的基本操作

目录 案例目的&#xff1a; 创建表&#xff1a; 创建offices&#xff1a; 创建employees表&#xff1a; 修改表&#xff1a; 将 employees 的 mobile 字段移动到 officeCode 字段后&#xff1a; 将 birth 字段名称改为 employee_birth: 修改 sex 字段&#xff0c;数据类…

Vue的路由实现:hash模式 和 history模式原理及区别

目录标题 1、hash模式2、history模式 Vue-Router有两种模式: ** hash 模式和 history**模式。默认的路由模式是hash模式。 1、hash模式 简介&#xff1a;hash模式是开发中默认的模式&#xff0c;它的URL带着一个#&#xff0c;例如:http://www.abc.com/#/vue&#xff0c;它的…

Facebook、Google、亚马逊,谁将成为跨境电商的营销宠儿?

跨境电商在全球范围内的发展日益迅猛&#xff0c;而营销渠道的选择也变得越来越多样化。在众多的广告平台中&#xff0c;Facebook、Google和亚马逊被公认为是跨境电商卖家们最主要的营销平台。那么&#xff0c;这三个平台中哪个会成为跨境电商的营销宠儿呢&#xff1f; 一、Fac…

【GIT】git push后长时间没反应

方向一 查看是否添加ssh 打开git bash cd ~/.ssh看是否成功&#xff0c;能成功说明之前生成过&#xff0c;看文件夹下是否有id_rsa.pub和id_rsa文件&#xff0c;有的话跳过生成步骤3 输入 ssh-keygen -t rsa -C ‘your_emailexample.com’(注&#xff1a;your_emailexample.c…

二百左右的蓝牙耳机哪款好?200左右音质最好的蓝牙耳机

在日常生活中离不开智能手机&#xff0c;特别是对无线蓝牙耳机的需求程度也越来越高&#xff0c;但是市面上有很多的蓝牙耳机戴久了耳朵会出现不舒服&#xff0c;为了获得更好的使用体验&#xff0c;我整理了市面上200左右价位佩戴和音质都表现不错的蓝牙耳机。 一、南卡小音舱…

“SCSA-T学习导图+”系列:IPSec VPN原理与应用

本期引言&#xff1a; 本章主要讲解IPSec VPN相关理论概念&#xff0c;工作原理。从安全和加密原理入手&#xff0c;讲解了IPSec 在VPN对等体设备实现的安全特性&#xff0c;如数据的机密性、数据的完整性&#xff0c;数据验证等。重点分析IPSec封装模式&#xff0c;IPSec安全…

【HDCTF2023】wp

【HDCTF2023】wp 文章目录 【HDCTF2023】wpwebWelcome To HDCTF 2023SearchMasterYamiYamiLoginMaster mischardMiscMasterMiscExtremeMiscSuperMisc web Welcome To HDCTF 2023 在源码的 game.js中找到了flag 在控制台输出 console.log(seeeeeeeecret)得flag SearchMaster …

亚马逊美国站带绳窗帘

带绳窗帘 如果您在亚马逊商城发布商品&#xff0c;则必须遵守适用于这些商品和商品信息的所有联邦、州和地方法律以及亚马逊政策&#xff08;包括本政策&#xff09;。 本政策涵盖的带绳窗帘 带绳窗帘是一种室内用窗帘&#xff0c;可通过一根吊绳控制升降。此类商品包括但不…

【PR 基础】轨道遮罩键、交叉溶解的简单使用

在上篇博客&#xff08;【PR 基础】裁剪工具的简单使用&#xff09;介绍了裁剪效果的使用&#xff0c;本篇博客在上篇的基础上继续添加 轨道遮罩键、交叉溶解的效果。 效果 步骤 1.可以先将恢复裁剪区域的关键帧删除 2. 接下来添加字幕&#xff0c;点击 新建-》旧版标题 点击…

vue3+ts+pinia+vite一次性全搞懂

vue3tspiniavite项目 一&#xff1a;新建一个vue3ts的项目二&#xff1a;安装一些依赖三&#xff1a;pinia介绍、安装、使用介绍pinia页面使用pinia修改pinia中的值 四&#xff1a;typescript的使用类型初识枚举 一&#xff1a;新建一个vue3ts的项目 前提是所处vue环境为vue3&…

flask学习-实践02

项目实战 入门文当(2条消息) python flask框架详解_flask python_尘世风的博客-CSDN博客(2条消息) python flask框架详解_flask python_尘世风的博客-CSDN博客 入门项目 抄作业了&#xff01;6 大 Flask 开源实战项目推荐_小詹学 Python的博客-CSDN博客 (66 条消息) GitHub 上有…

Transformer 位置编码代码解析

Transformer 位置编码代码解析 Transformer 的 Multi-Head-Attention 无法判断各个编码的位置信息。因此 Attention is all you need 中加入三角函数位置编码&#xff08;sinusoidal position embedding&#xff09;&#xff0c;表达形式为&#xff1a; P E ( p o s , 2 i ) …

OpenText Exceed TurboX (ETX) 安全功能介绍

OpenText Exceed TurboX (ETX) 安全功能介绍 将所有重要的知识产权&#xff08;IP &#xff09;相关数据保存在受良好保护的中央数据中心是保护 IP 的最佳做法。安全的远程访问是保护知识产权的关键。 所有数据流量均采用最新标准加密技术进行加密ETX 整合多种身份验证系统ET…

FE_TA不知道的CSS 换行系列【1】white-space

在W3C官方描述中&#xff0c;white-space主要有以下两个作用&#xff1a; 是否进行空格合并&#xff0c;以及控制空格合并的方式&#xff1b;是否在soft wrap opportunities&#xff08;文本中可进行换行的断点位置&#xff09;处进行文本换行。 从字面意思来看white-space即…

私人工具集6——使用C# 创建一个简单的restful风格的WebAPI

创建一个简单的WebApi 工具&#xff1a;VS2022 创建新项目 打开VS2022,创建新项目&#xff0c;可以搜索API作为关键字。 为项目取个名字 创建的应用程序&#xff0c;选择WebAPI&#xff0c;注意&#xff0c;右侧的信息默认即可&#xff0c;不要随意选择。 点击创建&#xff…

nodejs+vue 学分置换管理系统

在大学四年参加了各类竞赛后&#xff0c;我发现参加各类比赛存在报名过程过于繁琐&#xff0c;评比过程不透明和易出错等问题&#xff0c;所以在定题时与老师商讨后确定设计和实现基于nodejs的高校竞赛信息发布系统&#xff0c;帮助老师发布竞赛内容&#xff0c;便于同学们线上…

设计模式--建造者模式

项目需求 盖房需求 (1) 需要建房子:过程为 打地基 砌墙 封顶 (2) 房子有高正各样的,比如 平房和高楼 建房子的过程虽然都一样 但是要求不要相同的细节 传统方式 public abstract class TraditionBuild {//打地基public abstract void foundation();//砌墙public abstract voi…