当前位置: 首页 > news >正文

小谈设计模式(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)—访问者模式

小谈设计模式&#xff08;29&#xff09;—访问者模式 专栏介绍专栏地址专栏介绍 访问者模式角色分析访问者被访问者 优缺点分析优点将数据结构与算法分离增加新的操作很容易增加新的数据结构很困难4 缺点增加新的数据结构比较困难增加新的操作会导致访问者类的数量增加34 总结…...

【25】c++设计模式——>责任链模式

责任链模式定义 C中的责任链模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种行为型设计模式&#xff0c;它通过将请求沿着处理对象的链传递来避免把请求发送者与接收者耦合在一起。 责任链模式的主要思想是&#xff0c;通过将多个处理对象组成一条链&…...

GlobalTransactional

seata-spring的maven坐标&#xff1a; <dependency><groupId>io.seata</groupId><artifactId>seata-spring</artifactId><version>1.6.1</version> </dependency>GlobalTransactional注解的位置&#xff1a; io.seata.sprin…...

Android Studio运行kotlin项目,一直Read timed out

Android Studio运行kotlin项目&#xff0c;一直Read timed out 下载别人的Kotlin项目&#xff0c;导入as后&#xff0c;运行app一直失败&#xff0c;提示Read timed out&#xff0c;有2种解决办法 第一种方式&#xff1a;gradle.properties 修改kotlin项目种的gradle.proper…...

Excel 的单元格内容和单元格格式

文章目录 单元格内容单元格格式常规格式数字格式 单元格内容 文本&#xff1a;只要不是纯数字&#xff0c;Excel 都默认是文本格式。 在 Excel 中&#xff0c;逻辑值只有两个&#xff1a;True 和 False。 全选一片区域&#xff0c;按 Delet 键删除内容时&#xff0c;确实可以删…...

4大软件测试策略的特点和区别(单元测试、集成测试、确认测试和系统测试)

四大软件测试策略分别是单元测试、集成测试、确认测试和系统测试。 一、单元测试 单元测试也称为模块测试&#xff0c;它针对软件中的最小单元&#xff08;如函数、方法、类、模块等&#xff09;进行测试&#xff0c;以验证其是否符合预期的行为和结果。单元测试通常由开发人…...

armbian 安装mysql

1、执行安装指令 sudo apt-get update sudo apt-get install mysql-server 2、安装成功后&#xff0c;设置密码 ALTER USER root% IDENTIFIED WITH mysql_native_password BY ysw1234; flush privileges;3、设置允许远程连接并生效 use mysql; update user set host % whe…...

Ubuntu22常用软件

别存太多重要东西在Ubuntu &#xff0c;硬盘损坏就麻烦 Tweaks自定义UI sudo apt intall gnome-tweaks为了方便管理和添加&#xff0c;还需添加&#xff1a; sudo apt install gnome-shell-extension-prefs gnome-shell-extension-manager -y1.打开Extension应用&#xff0c;添…...

【CFD小工坊】浅水模型的边界条件

【CFD小工坊】浅水模型的边界条件 前言处理边界条件的原则边界处水力要素的计算水位边界条件单宽流量边界条件流量边界条件固壁边界条件 参考文献 前言 在浅水方程的离散及求解方法一篇中&#xff0c;我们学习了三角形网格各边通量值及源项的求解。但仍有一个问题没有解决&…...

电力物联网关智能通讯管理机-安科瑞黄安南

众所周知&#xff0c;网关应用于各种行业的终端设备的数据采集与数据分析&#xff0c;然后去实现设备的监测、控制、计算&#xff0c;为系统与设备之间建立通讯联系&#xff0c;达到双向的数据通讯。 网关可以实时监测并及时发现异常数据&#xff0c;同时自身根据用户规则进行…...

用Flask构建一个AI翻译服务

缘起 首先&#xff0c;看一段代码&#xff0c;只有几行Python语句却完成了AI翻译的功能。 #!/usr/bin/python3import sys from transformers import MarianMTModel, MarianTokenizerdef translate(word_list):model_name "Helsinki-NLP/opus-mt-en-zh"tokenizer …...

微信小程序引入阿里巴巴iconfont图标并使用

介绍 在小程序里&#xff0c;使用阿里巴巴的图标&#xff0c;如下所示: 使用方式 搜索自己需要的图标&#xff0c;然后将需要用到的图标加入购物车&#xff0c;如下图所示&#xff1a; 去右上角&#xff0c;点击购物车按钮&#xff1b;这里第一次使用&#xff0c;会有三个提…...

mysql面试题49:MySQL中不同text数据类型的最大长度

该文章专注于面试&#xff0c;面试只要回答关键点即可&#xff0c;不需要对框架有非常深入的回答&#xff0c;如果你想应付面试&#xff0c;是足够了&#xff0c;抓住关键点 面试官&#xff1a;MySQL中TEXT数据类型的最大长度 在MySQL中&#xff0c;TEXT数据类型用于存储较大…...

从虚拟电厂在上海的实践探索看企业微电网数字化的意义

安科瑞 华楠 作为典型的人口聚集、负荷密集区域&#xff0c;上海市具有外来电比例高、本地资源禀赋不足的特点。从发电侧角度来看&#xff0c;近年来上海风、光等新能源发电装机比例逐年提升&#xff0c;传统的火电逐渐成为调节性发电资源&#xff1b;从负荷侧角度来看上海以第…...

创建并初始化线程池

创建并初始化线程池–》threadpool.h, 创建并初始化&脱离(执行完后)子线程&#xff0c;每个子线程信号量wait阻塞【1】 创建套接字&#xff1a;int listenfd socket( PF_INET, SOCK_STREAM, 0 ); 端口复用&#xff1a;setsockopt( listenfd, SOL_SOCKET, SO_REUSEADDR, &a…...

【LeetCode热题100】--136.只出现一次的数字

136.只出现一次的数字 使用哈希表&#xff1a; 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激活函数的具体用法请查看此篇博客&#xff1a;LeakyReLU激活函数 ReLU&#xff08;Rectified Linear Unit&#xff09;激活函数是深度学习中最常用的激活函数之一&#xff0c;它的数学表达式如下&#xff1a; 在这里&#xff0c;(x) 是输入&#xff0c;(f(x)) 是输…...

【Android】adjustViewBounds 的理解和使用

理解 adjustViewBounds 是一个 ImageView 的属性&#xff0c;用于调整 ImageView 的边界以适应图像的尺寸。当设置为 true 时&#xff0c;ImageView 的边界将根据图像的宽高比例进行调整&#xff0c;以确保图像完全显示在 ImageView 内部。 理解和使用 adjustViewBounds 的步…...

Redis知识补充

大key删除 unLink scan分批删除 渐进式rehash Redis笔记&#xff1a;Redis的字典什么时候进行Rehash&#xff1f;_redis什么时候进行rehash-CSDN博客...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

【笔记】WSL 中 Rust 安装与测试完整记录

#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统&#xff1a;Ubuntu 24.04 LTS (WSL2)架构&#xff1a;x86_64 (GNU/Linux)Rust 版本&#xff1a;rustc 1.87.0 (2025-05-09)Cargo 版本&#xff1a;cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...

MySQL 部分重点知识篇

一、数据库对象 1. 主键 定义 &#xff1a;主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 &#xff1a;确保数据的完整性&#xff0c;便于数据的查询和管理。 示例 &#xff1a;在学生信息表中&#xff0c;学号可以作为主键&#xff…...

认识CMake并使用CMake构建自己的第一个项目

1.CMake的作用和优势 跨平台支持&#xff1a;CMake支持多种操作系统和编译器&#xff0c;使用同一份构建配置可以在不同的环境中使用 简化配置&#xff1a;通过CMakeLists.txt文件&#xff0c;用户可以定义项目结构、依赖项、编译选项等&#xff0c;无需手动编写复杂的构建脚本…...

【Post-process】【VBA】ETABS VBA FrameObj.GetNameList and write to EXCEL

ETABS API实战:导出框架元素数据到Excel 在结构工程师的日常工作中,经常需要从ETABS模型中提取框架元素信息进行后续分析。手动复制粘贴不仅耗时,还容易出错。今天我们来用简单的VBA代码实现自动化导出。 🎯 我们要实现什么? 一键点击,就能将ETABS中所有框架元素的基…...

Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践

前言&#xff1a;本文将向开发者介绍一款创新性协作工具——Neko虚拟浏览器。在数字化协作场景中&#xff0c;跨地域的团队常需面对实时共享屏幕、协同编辑文档等需求。通过本指南&#xff0c;你将掌握在Ubuntu系统中使用容器化技术部署该工具的具体方案&#xff0c;并结合内网…...

人工智能 - 在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型

在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型。这些平台各有侧重&#xff0c;适用场景差异显著。下面我将从核心功能定位、典型应用场景、真实体验痛点、选型决策关键点进行拆解&#xff0c;并提供具体场景下的推荐方案。 一、核心功能定位速览 平台核心定位技术栈亮…...