访问器模式(C++)

定义

表示一个作用于某对象结构中的各元素的操作。使得可以在不改变(稳定)各元素的类的前提下定义(扩展)作用于这些元素的新操作(变化)。

应用场景

  • 在软件构建过程中,由于需求的改变,某些类层次结构中常常需要增加新的行为(方法),如果直接在基类中做这样的更改,将会给子类带来很繁重的变更负担,甚至破坏原有设计。
  • 如何在不更改类层次结构的前提下,在运行时根据需要透明地为类层次结构上的各个类动态添加新的操作,从而避免上述问题?

结构

在这里插入图片描述

代码示例

//Visitor.h
/****************************************************/
#ifndef VISITOR_H
#define VISITOR_H
#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;
};// 接受访问
void School::accept(Visitor* visitor) {visitor->visitSchool(this);
}// 接受访问
void Enterprise::accept(Visitor* visitor) {visitor->visitEnterprise(this);
}#endif
//test.cpp
/****************************************************/
#include "Visitor.h"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;
}

运行结果
在这里插入图片描述

要点总结

  • Visitor模式通过所谓双重分发(double dispatch)来实现在不更改(不添加新的操作编译时) Element类层次结构的前提下,在运行时透明地为类层次结构上的各个类动态添加新的操作(支持变化)。
  • 所谓双重分发即Visitor模式中间包括了两个多态分发(注意其中的多态机制) :第一个为accept方法的多态辨析;第二个为visitElementX方法的多态辨析。
  • Visitor模式的最大缺点在于扩展类层次结构(增添新的Element子类),会导致Visitor类的改变。因此Vistor模式适用于“Element类层次结构稳定,而其中的操作却经常面临频繁改动”。

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

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

相关文章

7.2 手撕VGG11模型 使用Fashion_mnist数据训练VGG

VGG首先引入块的思想将模型通用模板化 VGG模型的特点 与AlexNet&#xff0c;LeNet一样&#xff0c;VGG网络可以分为两部分&#xff0c;第一部分主要由卷积层和汇聚层组成&#xff0c;第二部分由全连接层组成。 VGG有5个卷积块&#xff0c;前两个块包含一个卷积层&#xff0c…

11_Pulsar Adaptors适配器、kafka适配器、Spark适配器

2.3. Pulsar Adaptors适配器 2.3.1.kafka适配器 2.3.2.Spark适配器 2.3. Pulsar Adaptors适配器 2.3.1.kafka适配器 Pulsar 为使用 Apache Kafka Java 客户端 API 编写的应用程序提供了一个简单的解决方案。 在生产者中, 如果想不改变原有kafka的代码架构, 就切换到Pulsar的…

【ArcGIS】经纬度数据转化成平面坐标数据

将点位置导入Gis中&#xff0c;如下&#xff08;经纬度表征位置&#xff09;&#xff1a; 如何利用Gis将其转化为平面坐标呢&#xff1f; Step1 坐标变换 坐标变换&#xff0c;打开ArcToolbox&#xff0c;找到“数据管理工具”->“投影和变换”->“要素”->“投影”…

ChatGPT已闯入学术界,Elsevier推出AI工具

2022年11月&#xff0c;OpenAI公司发布了ChatGPT&#xff0c;这是迄今为止人工智能在现实世界中最重要的应用之一。 当前&#xff0c;互联网搜索引擎中出现了越来越多的人工智能&#xff08;AI&#xff09;聊天机器人&#xff0c;例如谷歌的Bard和微软的Bing&#xff0c;看起来…

掌握 JVM 调优命令

点击下方关注我&#xff0c;然后右上角点击...“设为星标”&#xff0c;就能第一时间收到更新推送啦~~~ JVM 日常调优总结起来就是&#xff1a;首先通过 jps 命令查看当前进程&#xff0c;然后根据 pid 通过 jinfo 命令查看和修改 jvm 参数&#xff0c;通过 jstat 命令查看 cla…

Go 语言并发编程 及 进阶与依赖管理

1.0 从并发编程本质了解Go高性能的本质 1.1 Goroutine 协程可以理解为轻量级线程&#xff1b; Go更适合高并发场景原因之一&#xff1a;Go语言一次可以创建上万协成&#xff1b; “快速”&#xff1a;开多个协成 打印。 go func(): 在函数前加 go 代表 创建协程; time.Sleep():…

软件开发人员这样跟踪时间,简单又有效!

作为软件开发人员&#xff0c;会有大量的代码需要编写&#xff0c;有大量的错误需要解决&#xff0c;有大量的功能需要构建。问题是&#xff0c;错误计算的任务堆积如山&#xff0c;很难正确掌握时间。 令人震惊的现实是&#xff0c;近一半的开发人员每周花在软件项目上的时间…

免费实用的日记应用:Day One for Mac中文版

Day One for Mac是一款运行在Mac平台上的日记软件&#xff0c;你可以使用Day One for mac通过快速菜单栏条目、提醒系统和鼓舞人心的信息来编写更多内容&#xff0c;day one mac版还支持Dropbox同步功能&#xff0c;想要day one mac中文免费版的朋友赶紧来试试吧&#xff01; …

AI模型公司如何定位 ?

AI模型公司如何定位 ? 企业与消费者&#xff1f; 和 多用途与利基市场&#xff1f; 文本将分解每个象限。 消费类和多用途 最有价值的象限并引发了人工智能热潮。 顶级公司&#xff1a; Open AI - 通过 ChatGPT 为消费者构建&#xff0c;并通过其旗舰 GPT 模型为企…

小鱼深度产品测评之:阿里云容器服务器ASK,一款不需购买节点,即可直接部署容器应用。

容器服务器ASK测评 1、引言2、帮助文档3、集群3.1集群列表3.1.1 详情3.1.1.1概览 tab3.1.1.2基本信息 tab3.1.1.4集群资源 tab3.1.1.5 集群日志 tab3.1.1.6 集群任务 tab 3.1.2 应用管理3.1.2.1 详情3.1.2.2 详情3.1.2.3 伸缩3.1.2.4 监控 3.1.3 查看日志3.1.3.1 集群日志3.1.3…

Vue组件化开发思想;Vue的全局组件;Vue的局部组件;Vue的开发模式和解析;Vue CLI安装和使用;Vue项目的创建方式–Vite

目录 1_Vue组件化开发思想1.1_认识组件化开发1.2_Vue的组件化1.3_注册组件的方式 2_Vue的全局组件3_Vue的局部组件4_Vue的开发模式和解析4.1_Vue的开发模式4.2_单文件的特点4.3_如何支持SFC4.4_VSCode对SFC文件的支持 5_Vue CLI安装和使用5.1_Vue CLI脚手架5.2_Vue CLI 安装和使…

基于SLAM的规划算法仿真复现|SLAM|智能规划

图片来自百度百科 前言 那么这里博主先安利一些干货满满的专栏了&#xff01; 首先是博主的高质量博客的汇总&#xff0c;这个专栏里面的博客&#xff0c;都是博主最最用心写的一部分&#xff0c;干货满满&#xff0c;希望对大家有帮助。 高质量博客汇总https://blog.csdn.n…