设计模式(4)--对象行为(11)--访问者

1. 意图

    表示一个作用于某对象结构中的各元素的操作。

    使你可以在不改变各元素的类的前提下定义于作用于这些元素的新操作。

2. 五种角色

    抽象访问者(Visitor)、具体访问者(Concrete Visitor)、抽象元素(Element)、

    具体元素(Concrete Element)、对象结构(ObjectStructure)

3. 优点

    3.1 易于增加新的操作

    3.2 集中相关的操作,而分离无关的操作

    3.3 可以访问不具有相同父类的对象

4. 缺点

    4.1 增加新的具体元素很困难

    4.2 可能累积状态

    4.3 可能破坏元素的封装性

5. 相关模式

    5.1 访问者可以对一个由Composite模式定义的对象结构进行操作。

    5.2 访问者可以用于解释器。

6. 代码示意
#pragma once
#include <vector>
#include <string>
#include <iostream>
using namespace std;class ElementA;
class ElementB;class Visitor
{
public:virtual void VisitElementA(ElementA* pElementA) = 0;virtual void VisitElementB(ElementB* pElementB) = 0;
};class ConcreteVisitor1 : public Visitor
{
public:virtual void VisitElementA(ElementA* pElementA);virtual void VisitElementB(ElementB* pElementB);
};
class ConcreteVisitor2 : public Visitor
{
public:virtual void VisitElementA(ElementA* pElementA);virtual void VisitElementB(ElementB* pElementB);
};class Element
{
public:virtual void Accept(Visitor* pVisitor) = 0;
};class ElementA : public Element
{
public:virtual void Accept(Visitor* pVisitor) {pVisitor->VisitElementA(this);}void OperationA(const string& name) {cout << "ElementA 来自 " << name << " 的访问" << endl;}
};class ElementB : public Element
{
public:virtual void Accept(Visitor* pVisitor) {pVisitor->VisitElementB(this);}void OperationB(const string& name) {cout << "ElementB 来自 " << name << " 的访问" << endl;}
};class ObjectStructure
{vector<Element*> m_elememts;
public:ObjectStructure() {m_elememts.emplace_back(new ElementA());m_elememts.emplace_back(new ElementB());}~ObjectStructure() {auto it = m_elememts.begin();while (it != m_elememts.end()) {delete* it;++it;}}void Visit(Visitor* pVisitor) {auto it = m_elememts.begin();while (it != m_elememts.end()) {(*it)->Accept(pVisitor);++it;}}
};

Visitor.cpp:

#include "Visitor.h"void ConcreteVisitor1::VisitElementA(ElementA* pElementA) {pElementA->OperationA("Visitor1");
}void ConcreteVisitor1::VisitElementB(ElementB* pElementB) {pElementB->OperationB("Visitor1");
}void ConcreteVisitor2::VisitElementA(ElementA* pElementA) {pElementA->OperationA("Visitor2");
}void ConcreteVisitor2::VisitElementB(ElementB* pElementB) {pElementB->OperationB("Visitor2");
}
#include "Visitor.h"
int main() {ObjectStructure* pObjStructure = new ObjectStructure();Visitor* pVisitor = new ConcreteVisitor1();pObjStructure->Visit(pVisitor);delete pVisitor;pVisitor = new ConcreteVisitor2();pObjStructure->Visit(pVisitor);delete pVisitor;delete pObjStructure;return 0;
}

 运行结果:

  6.1 ObjectStructure提供访问所有元素的接口

  6.2 增加新的ConcreteVisitor3就可以定义一个新的操作(3.1)

  6.3 抽象Visitor里的接口集中了相关的操作(3.2)

  6.4 增加新的ElementC,所有Visitor类和ObjectStructure都要修改(4.1)

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

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

相关文章

学习笔记15——前端和http协议

学习笔记系列开头惯例发布一些寻亲消息&#xff0c;感谢关注&#xff01; 链接&#xff1a;https://baobeihuijia.com/bbhj/ 关系 客户端&#xff1a;对连接访问到的前端代码进行解析和渲染&#xff0c;就是浏览器的内核服务器端&#xff1a;按照规则编写前端界面代码 解析标准…

Mysql 高级语句

目录 高阶查询select语句&#xff1a; 显示表格中一个或数个字段的所有数据记录&#xff1a; 不显示重复的数据记录&#xff1a;distinct and且&#xff0c;or或 显示已知的值的数据记录&#xff1a;in 显示两个值范围内的数据记录&#xff1a;between 通配符&#xff1…

UE蓝图 RPG动作游戏(一) day15

角色状态制作 制作角色动画混合空间 创建一个动混合空间 添加动作在混合空间 动画蓝图 创建一个动画蓝图 先使用混合空间进行移动&#xff0c;后续优化后再使用状态机 编写垂直水平速度逻辑初始化&#xff0c;获取到此动画的角色组件 获取Horizontal与Vertical的速度逻辑 …

CDH 6.3.2集成flink 1.18 zookeeper版本不匹配Flink-yarn启动失败

CDH 6.3.2集成flink 1.18 zookeeper版本不匹配Flink-yarn不能正常启动&#xff0c;而在CHD Web页面&#xff0c;flink日志报错提示不明确&#xff0c;不能定位具体错误。CM WEB启动失败错误日志如下图所示&#xff1a; CM查看完成错误日志 [31/Dec/2023 10:45:09 0000] 26000…

osg::DrawElements*系列函数及GL_QUAD_STRIP、GL_QUADS绘制四边形效率对比

目录 1. 前言 2. osg::DrawElements*系列函数用法说明 3. GL_QUADS、GL_QUAD_STRIP用法及不同点 4. 效率对比 5. 总结 6. 参考资料 1. 前言 利用osg绘制图元&#xff0c;如&#xff1a;三角形、四边形等&#xff0c;一般用osg::PrimitiveSet类。其派生出了很多子类&#…

使用docker build构建image

文章目录 环境步骤准备例1&#xff1a;基本用法例2&#xff1a;缓存layer例3&#xff1a;Multi-stage例4&#xff1a;Mountcache mountbind mount 例5&#xff1a;参数例6&#xff1a;Export文件例7&#xff1a;测试 参考 环境 RHEL 9.3Docker Community 24.0.7 步骤 在Dock…

Cookie、Session

一、会话管理 1、什么是会话&#xff1f; 会话是客户端和服务端之间进行多次的请求和响应。 相当于两个人聊天&#xff0c;进行了多次的问答。 对多次问答的管理叫做会话管理&#xff0c;管理的东西是通信状态。 2、什么是状态&#xff1f; 举例&#xff1a; 小明去校园食堂…

常用设计模式全面总结版(JavaKotlin)

这篇文章主要是针对之前博客的下列文章的总结版本: 《设计模式系列学习笔记》《Kotlin核心编程》笔记:设计模式【Android知识笔记】FrameWork中的设计模式主要为了在学习了 Kotlin 之后,将 Java 的设计模式实现与 Kotin 的实现放在一起做一个对比。 一、创建型模式 单例模…

以太网二层交换机实验

实验目的&#xff1a; &#xff08;1&#xff09;理解二层交换机的原理及工作方式&#xff1b; &#xff08;2&#xff09;利用交换机组建小型交换式局域网。 实验器材&#xff1a; Cisco packet 实验内容&#xff1a; 本实验可用一台主机去ping另一台主机&#xff0c;并…

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK设置相机的图像剪切(ROI)功能(C++)

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK设置相机的图像剪切&#xff08;ROI&#xff09;功能&#xff08;C&#xff09; Baumer工业相机Baumer工业相机的图像剪切&#xff08;ROI&#xff09;功能的技术背景CameraExplorer如何使用图像剪切&#xff08;ROI&#xff09;功…

Python武器库开发-武器库篇之Git的分支使用(三十九)

武器库篇之Git的分支使用(三十九) Git分支是一种用于在项目中并行开发和管理代码的功能。分支允许开发人员在不干扰主要代码的情况下创建新的代码版本&#xff0c;以便尝试新功能、修复错误或独立开发功能。一般正常情况下&#xff0c;开发人员开发一个软件&#xff0c;会有两…

HarmonyOS4.0系统性深入开发07创建一个ArkTS卡片

创建一个ArkTS卡片 在已有的应用工程中&#xff0c;创建ArkTS卡片&#xff0c;具体操作方式如下。 创建卡片。 根据实际业务场景&#xff0c;选择一个卡片模板。 在选择卡片的开发语言类型&#xff08;Language&#xff09;时&#xff0c;选择ArkTS选项&#xff0c;然后单…

nodejs+vue+微信小程序+python+PHP技术的健康信息网站-计算机毕业设计推荐

3.2 功能性需求分析 健康信息网站为会员提供健康信息服务的系统&#xff0c;管理员通过登录系统&#xff0c;管理会员信息、健康咨询、健康知识、健康档案、健康养生、健康信息的搜索、健康资讯等。需要学习的会员浏览健康信息网站&#xff0c;查询所有的健康信息&#xff0c;可…

【Java EE初阶三 】线程的状态与安全(下)

3. 线程安全 线程安全&#xff1a;某个代码&#xff0c;不管它是单个线程执行&#xff0c;还是多个线程执行&#xff0c;都不会产生bug&#xff0c;这个情况就成为“线程安全”。 线程不安全&#xff1a;某个代码&#xff0c;它单个线程执行&#xff0c;不会产生bug&#xff0c…

七:Day01_Java9—16新特性

第一章 JDK9 新特性 jdk9是新特性最多的&#xff0c;因为jdk8是一个稳定版本。 1、JDK9新特性概述 模块系统 &#xff08;Module System&#xff09; Java9最大特性。它提供了类似于OSGI框架的功能&#xff0c;模块之间存在相互的依赖关系&#xff0c;可以导出一个公共的API…

YOLOv8改进 | 2023注意力篇 | iRMB倒置残差块注意力机制(轻量化注意力机制)

一、本文介绍 本文给家大家带来的改进机制是iRMB&#xff0c;其是在论文Rethinking Mobile Block for Efficient Attention-based Models种提出&#xff0c;论文提出了一个新的主干网络EMO(后面我也会教大家如何使用该主干&#xff0c;本文先教大家使用该文中提出的注意力机制…

【Java进阶篇】什么是UUID,能不能保证唯一?

什么是UUID&#xff0c;能不能保证唯一? ✔️典型解析✔️优缺点 ✔️各个版本实现✔️V1.基于时间戳的UUID✔️V2.DCE(Distributed Computing Environment)安全的UUID✔️V3.基于名称空间的UUID(MD5)✔️V4.基于随机数的UUID✔️V5.基于名称空间的UUID(SHA1)✔️各个版本总结…

学生管理系统(vue + springboot)

学生管理系统&#xff08;vuespringboot&#xff09;资源-CSDN文库 项目介绍 这是一个采用前后端分离开发的项目&#xff0c;前端采用 Vue 开发、后端采用 Spring boot Mybatis 开发。 项目部署 ⭐️如果你有 docker 的话&#xff0c;直接 docker compose up 即可启动&#…

SpringBoot入门指南(学习笔记)

概述 Springboot是Spring的一个子项目&#xff0c;用于快速构建Spring应用程序 入门 ①创建SpringBoot工程 ②编写Controller RestController public class HelloContoller {RequestMapping("/hello")public String hello() {return "hello";} }③运行…

golang锁源码【只有关键逻辑】

条件锁 type Cond struct {L Lockernotify notifyList } type notifyList struct {wait uint32 //表示当前 Wait 的最大 ticket 值notify uint32 //表示目前已唤醒的 goroutine 的 ticket 的最大值lock uintptr // key field of the mutexhead unsafe.Pointer //链表头…