设计模式24——访问者模式

写文章的初心主要是用来帮助自己快速的回忆这个模式该怎么用,主要是下面的UML图可以起到大作用,在你学习过一遍以后可能会遗忘,忘记了不要紧,只要看一眼UML图就能想起来了。同时也请大家多多指教。

访问者模式(Visitor)

对象行为型模式。

目录

一、概述

1.1、直观的理解:

1.2、主要角色:

1.3、描述上述对象之间关系的UML图:

1.4、适用场景:

二、代码举例

2.1、对象之间的关系用UML图描述如下:

2.2、Java代码如下:


一、概述

1、表示一个作用于某对象结构中的各个元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作;

2、这算法应当是针对这数据结构里每一个对象建对应的处理,也就是算法对象里有一整个操作集合,使得每一个对象都可以根据不同的具体算法都同一时间段内单独的操作一下。而针对不同的时间段,又可以新建不同的算法类,同样算法类里也应该有在同一时间段里对那些数据结构类群里的所有对象的操作。

1.1、直观的理解

假设有3个元素,且对这些元素有两种操作需要实现,使用访问者模式我们逻辑上的思考应该是:

但在代码实现上,我们还需要再加一个枚举元素的类,他存储了所有相关的元素,并且可以枚举它们,方便访问者操作那些元素。

就拿访问者A访问元素1、2、3为例,活动图如下:

1.2、主要角色:

  • 访问者:访问者的抽象类或接口 + 访问者类,操作元素的类
  • 元素:元素的抽象类或接口 + 元素类,被操作的对象
  • 枚举元素类的类(ObjectStructure对象结构):保存着元素类的集合,并且可以遍历已保存的元素方便访问者访问

1.3、描述上述对象之间关系的UML图:

1.4、适用场景:

  • 一个对象结构包含很多类对象,它们有着不同的接口,而你想对这些对象实施一些依赖于其具体类的操作
  • 需要对一个对象结构中的对象进行很多不太并且不相关的操作,而你想要避免让这些操作“污染”这些对象的类
  • 适合于数据结构相对稳定的系统。它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由地演化

二、代码举例

假设有元素A和B,在它们之上有两类操作,那么设计出访问者1和2。这个例子比较简单,就不再详细分析了。但你可以把本例当做一个模板,然后灵活使用:

2.1、对象之间的关系用UML图描述如下:

2.2、Java代码如下:

访问者的抽象类:

abstract class Visitor {public abstract void visitConcreteElementA(ConcreteElementA concreteElementA);public abstract void visitConcreteElementB(ConcreteElementB concreteElementB);
}

元素的抽象类:

abstract class Element {public abstract void accept(Visitor visitor);
}

元素类A:

public class ConcreteElementA extends Element{@Overridepublic void accept(Visitor visitor) {visitor.visitConcreteElementA(this);}//其他操作
}

元素类B:

public class ConcreteElementB extends Element{@Overridepublic void accept(Visitor visitor) {visitor.visitConcreteElementB(this);}//其他操作
}

访问者1:

public class ConcreteVisitor1 extends Visitor {@Overridepublic void visitConcreteElementA(ConcreteElementA concreteElementA) {System.out.println(concreteElementA.getClass().getSimpleName() + "被" + this.getClass().getSimpleName() + "访问");}@Overridepublic void visitConcreteElementB(ConcreteElementB concreteElementB) {System.out.println(concreteElementB.getClass().getSimpleName() + "被" + this.getClass().getSimpleName() + "访问");}
}

访问者2:

public class ConcreteVisitor2 extends Visitor {@Overridepublic void visitConcreteElementA(ConcreteElementA concreteElementA) {System.out.println(concreteElementA.getClass().getSimpleName() + "被" + this.getClass().getSimpleName() + "访问");}@Overridepublic void visitConcreteElementB(ConcreteElementB concreteElementB) {System.out.println(concreteElementB.getClass().getSimpleName() + "被" + this.getClass().getSimpleName() + "访问");}
}

枚举元素类的类:

public class ObjectStructure {private List<Element> elements = new ArrayList<>();public void attach(Element element) {elements.add(element);}public void detach(Element element) {elements.remove(element);}public void accept(Visitor visitor) {for (Element element : elements) {element.accept(visitor);}}
}

主程序(发起请求的类):

public class Main {public static void main(String[] args) {ObjectStructure objectStructure = new ObjectStructure();objectStructure.attach(new ConcreteElementA());objectStructure.attach(new ConcreteElementB());objectStructure.accept(new ConcreteVisitor1());objectStructure.accept(new ConcreteVisitor2());}
}

这里就不再举例了,可以把上面的Java例子复制到你本地,运行main函数试一下加深理解。这些代码都是我自己学习的时候根据一些教材手敲的,不存在bug可以直接运行。

如果觉得本文还不错,就请点个赞给作者一点鼓励吧!如果有建议,也请评论指教和讨论!

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

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

相关文章

cuda编程笔记(2)--传递参数、设备属性

以下是最简单的带参数的核函数使用过程&#xff1a; #include<iostream> #include<cstdio> #include "cuda_runtime.h" #include "device_launch_parameters.h" __global__ void add(int a,int b,int *c) {*c a b; } int main() {int c;int…

C# WinForm应用程序多语言实现全面指南

目录 引言 一、多语言实现基础概念 1.1 多语言实现的核心原理 1.2 .NET本地化支持机制 二、基于XML的多语言实现方案 2.1 方案概述 2.2 XML文件结构示例 2.3 实现步骤 2.4 优缺点分析 三、基于.resx资源文件的多语言实现 3.1 方案概述 3.2 实现步骤 3.3 资源文件结…

Python爬虫实战:研究Playwright框架相关技术

1 引言 1.1 研究背景与意义 网络爬虫作为一种自动获取互联网信息的技术,在数据采集、信息监测、竞争情报等领域具有广泛应用。随着 Web 技术的发展,越来越多的网站采用 JavaScript 动态渲染技术,传统爬虫工具难以有效获取完整的页面内容。Playwright 作为新一代自动化测试…

中企出海大会|打造全球化云计算一张网,云网络助力中企出海和AI创新

全球化是阿里云的长期战略&#xff0c;未来阿里云将持续加大云和 AI 基础设施建设投入。首先是加速打造全球化的云计算网络&#xff0c;一张具备 AI技术服务能力和全球竞争力的云计算网络是阿里云的长期目标。 —— 阿里巴巴集团 CEO、阿里云智能集团董事长兼 CEO 吴泳铭 5 月 …

唯创WT2606B TFT显示灵动方案,重构电子锁人机互动界面,赋能智能门锁全场景交互!

在智能家居的浪潮中&#xff0c;门锁搭载显示屏已成为行业创新的焦点。据行业数据显示&#xff0c;2023年全球智能门锁出货量中&#xff0c;搭载显示屏的型号占比已突破40%&#xff0c;且年复合增长率达25%。而2024年国内智能门锁销量突破2200万套&#xff0c;预计2025年市场规…

轻量化开源方案——浅析PdfPatcher实际应用

PDF处理在实际工作中十分重要&#xff0c;今天浅析PdfPatcher在PDF处理中的实际应用。 核心功能实测 批量处理能力 支持修改文档属性/页码编号/页面链接 一键清除复制/打印限制&#xff08;实测WPS加密文档可解锁&#xff09; 自动清理隐藏冗余数据&#xff08;经测试可平均…

Docker 环境搭建与三大数据库(MySQL/Redis/MongoDB)部署教程

Docker 环境搭建与三大数据库(MySQL/Redis/MongoDB)部署教程 一、简介二、安装wsl三、wsl磁盘迁移四、wsl磁盘压缩五、Docker下载六、win11配置docker虚拟环境命令工具七、Docker部署mysql八、Docker部署redis九、Docker部署mongo一、简介 Docker 是一个开源的容器化平台,它…

CPO-BP+MOPSO,冠豪猪优化BP神经网络+多目标粒子群算法!(Matlab源码)

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.CPO-BPNSGA&#xff0c;冠豪猪优化BP神经网络粒子群算法&#xff01;&#xff08;Matlab完整源码和数据&#xff09;&#xff0c;冠豪猪算法优化BP神经网络的权值和阈值&#xff0c;运行环境Matlab2020b及以上。 多…

Vision Pro发布!开发者如何快速上手空间UI设计?

Vision Pro发布&#xff01;开发者如何快速上手空间UI设计&#xff1f; 【内容摘要】 苹果最新发布的Vision Pro&#xff0c;不仅重新定义了我们对虚拟现实&#xff08;VR&#xff09;和增强现实&#xff08;AR&#xff09;的认知&#xff0c;也为开发者们带来了前所未有的机…

Bootstrap法进行随机模拟

一、问题背景 # 26名神经功能受损儿童接受了两组&#xff08;A组与B组&#xff09;空间知觉测试&#xff0c;得分如下A组和B组数据。 # A组数据 x_A <- c(48, 36, 20, 29, 42, 42, 20, 42, 22, 41, 45, 14, 6, 0, 33, 28, 34, 4, 32, 24, 47, 41, 24, 26, 30, 41)# B组数据…

Spring AI 多模型智能协作工作流实现指南

Spring AI 多模型智能协作工作流实现指南 说明 本文档旨在指导开发者基于 Spring AI 框架&#xff0c;在 Spring Boot 2 环境下集成多种主流大语言模型&#xff08;如 OpenAI ChatGPT、Deepseek、阿里云通义千问等&#xff09;&#xff0c;并提供从环境配置、模型调用、流式输…

C语言中清空缓存区到底写到哪里比较好

文章目录 问题背景%d和%c读取缓冲区的差别清空缓存区 问题背景 在写C语言的命令行程序时&#xff0c;我们经常会用到用户输入和标准输出&#xff0c;特别的&#xff0c;当用户输入后&#xff0c;我们发现程序运行不是我们要的样子&#xff0c;这个时候&#xff0c;很可能就是输…

计算机视觉与深度学习 | 基于 YOLOv8 + BeautyGAN + CodeFormer + Face Parsing 实现简单的人脸美颜

人脸美颜 **一、算法流程图****二、完整代码实现**1. 环境准备2. 完整代码(face_beautify.py)**三、核心算法公式**1. YOLOv8检测损失函数2. BeautyGAN损失函数3. CodeFormer图像重建公式**四、关键实现细节**1. 多尺度人脸处理2. 颜色校正策略**五、模型下载清单****六、性能…

如何在WordPress中选择最佳Elementor主题:专家指南

当你在WordPress建站过程中逐步积累了经验&#xff0c;你可能会发觉&#xff0c;基础和进阶主题已难以完全满足你的需求。如果你需要更复杂的功能、更灵活的布局设计&#xff0c;甚至高级定制效果&#xff0c;那么就需要选择更加专业的主题。在这篇文章中&#xff0c;我将为你推…

FPGA高速接口 mipi lvds cameralink hdml 千兆网 sdi

mipi: https://blog.csdn.net/SDJ_success/article/details/146541776 cameralink CameraLink协议 CameraLink协议是一种专门针对机器视觉应用领域的串行通信协议&#xff0c;它使用低压差分信号(LVDS)进行数据的传输和通信。CameraLink标准是在ChannelLink标准的基础上多加了…

手机收不到WiFi,手动输入WiFi名称进行连接不不行,可能是WiFi频道设置不对

以下是电脑上分享WiFi后&#xff0c;部分手机可以看到并且能连接&#xff0c;部分手机不行&#xff0c;原因是&#xff1a;频道设置为5GHz&#xff0c;修改成&#xff0c;任何可用频率&#xff0c;则可

12.Java 对象冷冻术:从用户登录到游戏存档的序列化实战

目录 一、引言 二、用户登录存档&#xff1a;让账号信息「冻龄」不变 1. 给对象贴「冷冻标签」&#xff1a;实现 Serializable 2. 冷冻与解冻实战&#xff1a;把用户存进文件 3. 演示场景 三、游戏存档复活&#xff1a;让角色进度「穿越时空」 1. 复杂对象冷冻&#xff…

conda 环境中opencv 报错以及其他报错

如题&#xff0c;通过 conda install opencv 然后遇到 ImportError: DLL load failed while importing cv2: 找不到指定的模块。 参考网络相关答案 通过conda 卸载 然后通过 pip3 安装opencv-pyhton https://stackoverflow.com/questions/75387197/anaconda-importerror-dll-…

(已开源-CVPR2024) RadarDistill---NuScenes数据集Radar检测第一名

本文介绍一篇Radar 3D目标检测模型&#xff1a;RadarDistill。雷达数据固有的噪声和稀疏性给3D目标检测带来了巨大挑战。在本文中&#xff0c;作者提出了一种新的知识蒸馏(KD)方法RadarDistill&#xff0c;它可以通过利用激光雷达数据来提高雷达数据的表征。RadarDistill利用三…

创建型设计模式之Singleton(单例)设计模式

创建型设计模式之Singleton&#xff08;单例&#xff09;设计模式 摘要&#xff1a; Singleton&#xff08;单例&#xff09;设计模式确保一个类仅有一个实例&#xff0c;并提供全局访问点。其结构包含一个静态方法getInstance()用于获取唯一实例&#xff0c;构造方法私有化防…