小谈设计模式(29)—访问者模式
小谈设计模式(29)—访问者模式
- 专栏介绍
- 专栏地址
- 专栏介绍
- 访问者模式
- 角色分析
- 访问者
- 被访问者
- 优缺点分析
- 优点
- 将数据结构与算法分离
- 增加新的操作很容易
- 增加新的数据结构很困难
- 4
- 缺点
- 增加新的数据结构比较困难
- 增加新的操作会导致访问者类的数量增加
- 3
- 4
- 总结
- Java程序示例
- 要求:
- 首先,我们定义一个抽象的图形类(Element),其中包含一个接受访问者的方法 accept(),以及一个抽象的计算面积和周长的方法 calculate()。
- 接下来,我们定义一个访问者接口(Visitor),其中包含了访问圆形和矩形的方法 visit()。
- 然后,我们实现具体的访问者类(AreaVisitor和PerimeterVisitor),分别用于计算图形的面积和周长。
- 最后,我们可以在客户端代码中使用访问者模式来计算图形的面积和周长。
- 程序分析
- 总结
专栏介绍
专栏地址
http://t.csdnimg.cn/VpriY
专栏介绍
主要对目前市面上常见的23种设计模式进行逐一分析和总结,希望有兴趣的小伙伴们可以看一下,会持续更新的。希望各位可以监督我,我们一起学习进步,加油,各位

访问者模式
访问者模式是一种行为型设计模式,它允许你将算法与一个对象结构分离开来。通过这种方式,可以在不改变对象结构的情况下,向对象结构中添加新的操作。

角色分析
访问者(Visitor)和被访问者(Element)
访问者
定义了一组可以访问不同类型被访问者的方法
被访问者
定义了接受访问者的方法。访问者通过被访问者的接口访问被访问者,并对其进行操作。

优缺点分析
优点
将数据结构与算法分离
访问者模式可以将数据结构与算法分离,使得算法可以独立于数据结构而变化,提高了代码的可维护性和可扩展性。
增加新的操作很容易
当需要增加新的操作时,只需要增加一个新的访问者类即可,不需要修改原有的代码。
增加新的数据结构很困难
当需要增加新的数据结构时,需要修改所有的访问者类,因此增加新的数据结构比较困难。
4
访问者模式符合单一职责原则和开闭原则

缺点
增加新的数据结构比较困难
当需要增加新的数据结构时,需要修改所有的访问者类,因此增加新的数据结构比较困难。
增加新的操作会导致访问者类的数量增加
当需要增加新的操作时,需要增加一个新的访问者类,因此访问者类的数量会增加。
3
导致系统变得复杂,增加了代码的阅读难度。
4
访问者模式需要对数据结构进行抽象,增加了系统的抽象性和理解难度。
总结
访问者模式适用于数据结构相对稳定,但是经常需要增加新的操作的场景,同时访问者模式也需要权衡系统的复杂度和可维护性。

Java程序示例
要求:
为一个图形库添加一个新的功能,即计算图形的面积和周长。我们可以使用访问者模式来实现这个功能。
首先,我们定义一个抽象的图形类(Element),其中包含一个接受访问者的方法 accept(),以及一个抽象的计算面积和周长的方法 calculate()。
abstract class Shape {public abstract void accept(Visitor visitor);public abstract void calculate();
}```
### 然后,我们定义两个具体的图形类,圆形和矩形,它们都继承自图形类。
```java
class Circle extends Shape {private double radius;public Circle(double radius) {this.radius = radius;}public double getRadius() {return radius;}public void accept(Visitor visitor) {visitor.visit(this);}public void calculate() {System.out.println("Calculating area and perimeter of circle");}
}class Rectangle extends Shape {private double width;private double height;public Rectangle(double width, double height) {this.width = width;this.height = height;}public double getWidth() {return width;}public double getHeight() {return height;}public void accept(Visitor visitor) {visitor.visit(this);}public void calculate() {System.out.println("Calculating area and perimeter of rectangle");}
}
接下来,我们定义一个访问者接口(Visitor),其中包含了访问圆形和矩形的方法 visit()。
interface Visitor {void visit(Circle circle);void visit(Rectangle rectangle);
}
然后,我们实现具体的访问者类(AreaVisitor和PerimeterVisitor),分别用于计算图形的面积和周长。
class AreaVisitor implements Visitor {public void visit(Circle circle) {double area = Math.PI * circle.getRadius() * circle.getRadius();System.out.println("Area of circle: " + area);}public void visit(Rectangle rectangle) {double area = rectangle.getWidth() * rectangle.getHeight();System.out.println("Area of rectangle: " + area);}
}class PerimeterVisitor implements Visitor {public void visit(Circle circle) {double perimeter = 2 * Math.PI * circle.getRadius();System.out.println("Perimeter of circle: " + perimeter);}public void visit(Rectangle rectangle) {double perimeter = 2 * (rectangle.getWidth() + rectangle.getHeight());System.out.println("Perimeter of rectangle: " + perimeter);}
}
最后,我们可以在客户端代码中使用访问者模式来计算图形的面积和周长。
public static void main(String[] args) {List<Shape> shapes = new ArrayList<>();shapes.add(new Circle(5));shapes.add(new Rectangle(3, 4));Visitor areaVisitor = new AreaVisitor();Visitor perimeterVisitor = new PerimeterVisitor();for (Shape shape : shapes) {shape.accept(areaVisitor);shape.accept(perimeterVisitor);}
}
程序分析
在上面的代码中,我们创建了一个包含圆形和矩形的列表,并分别使用面积访问者和周长访问者来计算每个图形的面积和周长。

总结
访问者模式可以帮助我们将算法与对象结构分离开来,提高代码的可维护性和可扩展性。在实现访问者模式时,需要定义一个抽象的被访问者类和访问者接口,然后实现具体的被访问者类和访问者类。在客户端代码中,可以使用访问者来访问被访问者,并对其进行操作。
相关文章:
小谈设计模式(29)—访问者模式
小谈设计模式(29)—访问者模式 专栏介绍专栏地址专栏介绍 访问者模式角色分析访问者被访问者 优缺点分析优点将数据结构与算法分离增加新的操作很容易增加新的数据结构很困难4 缺点增加新的数据结构比较困难增加新的操作会导致访问者类的数量增加34 总结…...
【25】c++设计模式——>责任链模式
责任链模式定义 C中的责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它通过将请求沿着处理对象的链传递来避免把请求发送者与接收者耦合在一起。 责任链模式的主要思想是,通过将多个处理对象组成一条链&…...
GlobalTransactional
seata-spring的maven坐标: <dependency><groupId>io.seata</groupId><artifactId>seata-spring</artifactId><version>1.6.1</version> </dependency>GlobalTransactional注解的位置: io.seata.sprin…...
Android Studio运行kotlin项目,一直Read timed out
Android Studio运行kotlin项目,一直Read timed out 下载别人的Kotlin项目,导入as后,运行app一直失败,提示Read timed out,有2种解决办法 第一种方式:gradle.properties 修改kotlin项目种的gradle.proper…...
Excel 的单元格内容和单元格格式
文章目录 单元格内容单元格格式常规格式数字格式 单元格内容 文本:只要不是纯数字,Excel 都默认是文本格式。 在 Excel 中,逻辑值只有两个:True 和 False。 全选一片区域,按 Delet 键删除内容时,确实可以删…...
4大软件测试策略的特点和区别(单元测试、集成测试、确认测试和系统测试)
四大软件测试策略分别是单元测试、集成测试、确认测试和系统测试。 一、单元测试 单元测试也称为模块测试,它针对软件中的最小单元(如函数、方法、类、模块等)进行测试,以验证其是否符合预期的行为和结果。单元测试通常由开发人…...
armbian 安装mysql
1、执行安装指令 sudo apt-get update sudo apt-get install mysql-server 2、安装成功后,设置密码 ALTER USER root% IDENTIFIED WITH mysql_native_password BY ysw1234; flush privileges;3、设置允许远程连接并生效 use mysql; update user set host % whe…...
Ubuntu22常用软件
别存太多重要东西在Ubuntu ,硬盘损坏就麻烦 Tweaks自定义UI sudo apt intall gnome-tweaks为了方便管理和添加,还需添加: sudo apt install gnome-shell-extension-prefs gnome-shell-extension-manager -y1.打开Extension应用,添…...
【CFD小工坊】浅水模型的边界条件
【CFD小工坊】浅水模型的边界条件 前言处理边界条件的原则边界处水力要素的计算水位边界条件单宽流量边界条件流量边界条件固壁边界条件 参考文献 前言 在浅水方程的离散及求解方法一篇中,我们学习了三角形网格各边通量值及源项的求解。但仍有一个问题没有解决&…...
电力物联网关智能通讯管理机-安科瑞黄安南
众所周知,网关应用于各种行业的终端设备的数据采集与数据分析,然后去实现设备的监测、控制、计算,为系统与设备之间建立通讯联系,达到双向的数据通讯。 网关可以实时监测并及时发现异常数据,同时自身根据用户规则进行…...
用Flask构建一个AI翻译服务
缘起 首先,看一段代码,只有几行Python语句却完成了AI翻译的功能。 #!/usr/bin/python3import sys from transformers import MarianMTModel, MarianTokenizerdef translate(word_list):model_name "Helsinki-NLP/opus-mt-en-zh"tokenizer …...
微信小程序引入阿里巴巴iconfont图标并使用
介绍 在小程序里,使用阿里巴巴的图标,如下所示: 使用方式 搜索自己需要的图标,然后将需要用到的图标加入购物车,如下图所示: 去右上角,点击购物车按钮;这里第一次使用,会有三个提…...
mysql面试题49:MySQL中不同text数据类型的最大长度
该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:MySQL中TEXT数据类型的最大长度 在MySQL中,TEXT数据类型用于存储较大…...
从虚拟电厂在上海的实践探索看企业微电网数字化的意义
安科瑞 华楠 作为典型的人口聚集、负荷密集区域,上海市具有外来电比例高、本地资源禀赋不足的特点。从发电侧角度来看,近年来上海风、光等新能源发电装机比例逐年提升,传统的火电逐渐成为调节性发电资源;从负荷侧角度来看上海以第…...
创建并初始化线程池
创建并初始化线程池–》threadpool.h, 创建并初始化&脱离(执行完后)子线程,每个子线程信号量wait阻塞【1】 创建套接字:int listenfd socket( PF_INET, SOCK_STREAM, 0 ); 端口复用:setsockopt( listenfd, SOL_SOCKET, SO_REUSEADDR, &a…...
【LeetCode热题100】--136.只出现一次的数字
136.只出现一次的数字 使用哈希表: class Solution {public int singleNumber(int[] nums) {Map<Integer,Integer> map new HashMap<>();for(int num:nums){Integer count map.get(num);if(count null){count 1;}else{count;}map.put(num,count);}…...
Java idea查看自定义注解的调用地方
Java idea查看自定义注解的调用地方...
ReLU激活函数
LeakyReLU激活函数的具体用法请查看此篇博客:LeakyReLU激活函数 ReLU(Rectified Linear Unit)激活函数是深度学习中最常用的激活函数之一,它的数学表达式如下: 在这里,(x) 是输入,(f(x)) 是输…...
【Android】adjustViewBounds 的理解和使用
理解 adjustViewBounds 是一个 ImageView 的属性,用于调整 ImageView 的边界以适应图像的尺寸。当设置为 true 时,ImageView 的边界将根据图像的宽高比例进行调整,以确保图像完全显示在 ImageView 内部。 理解和使用 adjustViewBounds 的步…...
Redis知识补充
大key删除 unLink scan分批删除 渐进式rehash Redis笔记:Redis的字典什么时候进行Rehash?_redis什么时候进行rehash-CSDN博客...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...
IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...
ui框架-文件列表展示
ui框架-文件列表展示 介绍 UI框架的文件列表展示组件,可以展示文件夹,支持列表展示和图标展示模式。组件提供了丰富的功能和可配置选项,适用于文件管理、文件上传等场景。 功能特性 支持列表模式和网格模式的切换展示支持文件和文件夹的层…...
