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

设计模式(23):访问者模式

定义

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

模式动机

  • 对于存储在一个集合中的对象,他们可能具有不同的类型(即使有一个公共的接口),对于该集合中的对象,可以接受一类称为访问者的对象来访问,不同的访问者其访问方式也有所不同。

访问者模式角色

  • 抽象访问者: 一般通过visit方法声明可以访问哪写元素;
  • 具体访问者: 实现抽象访问者。访问元素的内容;
  • 抽象元素: 需要被访问的对象。一般有一个accept方法接受访问者方法;
  • 具体元素: 实现了抽象元素。在accept方法中调用访问者的visit方法;

开发中常见的场景

  • XML文挡解释器设计
  • 编译器的设计
  • 复杂集合对象的处理

总结

  • 访问者模式是GOF23种设计模式中最复杂的一种设计模式,一般在工作中不会使用访问者设计模式,也尽量不要使用访问者设计模式;如果用到了访问者设计模式,那就是必须要使用访问者设计模式啦。

代码实现

  • 抽象访问者
/*** 抽象访问者*/
public interface Visitor {void visit(ManElement manElement);void visit(WomanElement womanElement);
}
  • 具体访问者
/*** 具体访问者NameVisitor*/
public class NameVisitor implements Visitor {@Overridepublic void visit(ManElement manElement) {System.out.println("名称:"+manElement.getName());}@Overridepublic void visit(WomanElement womanElement) {System.out.println("名称:"+womanElement.getName());}
}
/*** 具体访问者GenderVisitor*/
public class GenderVisitor implements Visitor {@Overridepublic void visit(ManElement manElement) {System.out.println("性别:男");}@Overridepublic void visit(WomanElement womanElement) {System.out.println("性别:女");}
}
/*** 具体访问者AgeVisitor*/
public class AgeVisitor implements Visitor {@Overridepublic void visit(ManElement manElement) {System.out.println("年龄:"+manElement.getAge());}@Overridepublic void visit(WomanElement womanElement) {System.out.println("年龄:"+womanElement.getAge());}
}
  • 抽象元素
/*** 抽象元素*/
public interface Element {void accept(Visitor visitor);}
  • 具体元素
/*** 人*/
public interface Person {String getName();Boolean isMan();Integer getAge();
}
/*** 具体元素ManElement */
public class ManElement implements Person, Element{private String name;private Boolean isMan = true;private Integer age;public ManElement() {}public ManElement(String name, Integer age) {super();this.name = name;this.age = age;}@Overridepublic void accept(Visitor visitor) {visitor.visit(this);}@Overridepublic String getName() {return name;}@Overridepublic Boolean isMan() {return isMan;}@Overridepublic Integer getAge() {return age;}public Boolean getIsMan() {return isMan;}public void setName(String name) {this.name = name;}public void setAge(Integer age) {this.age = age;}
}
/*** 具体元素WomanElement */
public class WomanElement implements Person,Element{private String name;private Boolean isMan = false;private Integer age;@Overridepublic void accept(Visitor visitor) {visitor.visit(this);}public WomanElement() {}public WomanElement(String name, Integer age) {super();this.name = name;this.age = age;}@Overridepublic String getName() {return name;}@Overridepublic Boolean isMan() {return isMan;}@Overridepublic Integer getAge() {return age;}public Boolean getIsMan() {return isMan;}public void setName(String name) {this.name = name;}public void setAge(Integer age) {this.age = age;}
}
  • 客户端调用
public static void main(String[] args) {ManElement manElement = new ManElement("张三", 30);WomanElement womanElement = new WomanElement("翠花", 18);List<Element> elements = new ArrayList<>();elements.add(manElement);elements.add(womanElement);NameVisitor nameVisitor = new NameVisitor();GenderVisitor genderVisitor = new GenderVisitor();AgeVisitor ageVisitor = new AgeVisitor();for (Element element : elements) {element.accept(nameVisitor);element.accept(genderVisitor);element.accept(ageVisitor);}
}



更多设计模式学习:

          设计模式(1):介绍
          设计模式(2):单例模式
          设计模式(3):工厂模式
          设计模式(4):建造者模式
          设计模式(5):原型模式
          设计模式(6):桥接模式
          设计模式(7):装饰器模式
          设计模式(8):组合模式
          设计模式(9):外观模式
          设计模式(10):享元模式
          设计模式(11):适配器模式
          设计模式(12):代理模式
          设计模式(13):模板方法模式
          设计模式(14):命令模式
          设计模式(15):迭代器模式
          设计模式(16):观察者模式
          设计模式(17):中介者模式
          设计模式(18):状态模式
          设计模式(19):策略模式
          设计模式(20):责任链模式
          设计模式(21):备忘录模式
          设计模式(22):解释器模式
          设计模式(23):访问者模式

相关文章:

设计模式(23):访问者模式

定义 表示一个作用于某对象结构中的各元素的操作&#xff0c;它使我们可以在不改变元素的类的前提下定义作用与这些元素的新操作。 模式动机 对于存储在一个集合中的对象&#xff0c;他们可能具有不同的类型(即使有一个公共的接口)&#xff0c;对于该集合中的对象&#xff0…...

【C++】类和对象③(类的默认成员函数:拷贝构造函数 | 赋值运算符重载)

&#x1f525;个人主页&#xff1a;Forcible Bug Maker &#x1f525;专栏&#xff1a;C 目录 前言 拷贝构造函数 概念 拷贝构造函数的特性及用法 赋值运算符重载 运算符重载 赋值运算符重载 结语 前言 本篇主要内容&#xff1a;类的6个默认成员函数中的拷贝构造函数…...

掀起区块链开发狂潮!Scaffold-eth带你一键打造震撼DApp

文章目录 前言一、Scaffold-eth是什么&#xff1f;二、安装和配置1.准备工作2.安装3.配置开发环境 三、进阶使用1.放入自己的合约2.部署运行 总结 前言 前面的文章传送&#x1f6aa;&#xff1a;hardhat入门 与 hardhat进阶 在之前的文章中&#xff0c;我们已经探讨了使用Har…...

【Qt 学习笔记】Qt常用控件 | 按钮类控件Check Box的使用及说明

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Qt常用控件 | 按钮类控件Check Box的使用及说明 文章编号&#xff1a;…...

android gradle 配置远程仓库

build.gradle buildscript { ext.kotlin_version "1.6.0" // 使用适合你项目的Kotlin版本 repositories { maven { url http://maven.aliyun.com/nexus/content/groups/public/ } maven { url http://maven.aliyun.com/nexus/content/repos…...

第十二章 OpenGL ES 基础-色温、色调、亮度、对比度、饱和度、高光

第十二章 OpenGL ES 基础-色温、色调、亮度、对比度、饱和度、高光 第一章 OpenGL ES 基础-屏幕、纹理、顶点坐标 第二章 OpenGL ES 基础-GLSL语法简单总结 第三章 OpenGL ES 基础-GLSL渲染纹理 第四章 OpenGL ES 基础-位移、缩放、旋转原理 第五章 OpenGL ES 基础-透视投影…...

力扣经典150题解析之二十八:盛最多水的容器

目录 力扣经典150题解析之二十八&#xff1a;盛最多水的容器1. 介绍2. 问题描述3. 示例4. 解题思路5. 算法实现6. 复杂度分析7. 测试与验证测试用例设计测试结果分析 8. 总结9. 参考文献感谢阅读 力扣经典150题解析之二十八&#xff1a;盛最多水的容器 1. 介绍 在这篇文章中&…...

Rockchip Android13 Vold(二):Framework层

目录 前言 1、接收VolumeInfo状态 2、通知VolumeInfo状态变化 3、创建StorageVolume...

Oracle数据库故障类别及日常运维规划策略

一、故障类别 1、语句故障 单个数据库操作失败&#xff08;select、insert、update或delete&#xff09;&#xff0c;如&#xff1a; 在表中输入无效的数据&#xff0c;解决方法&#xff1a;可与用户合作来验证并更正数据&#xff1b;执行操作&#xff0c;但权限不足&#x…...

电商技术揭秘九:搜索引擎中的SEO数据分析与效果评估

相关系列文章 电商技术揭秘一&#xff1a;电商架构设计与核心技术 电商技术揭秘二&#xff1a;电商平台推荐系统的实现与优化 电商技术揭秘三&#xff1a;电商平台的支付与结算系统 电商技术揭秘四&#xff1a;电商平台的物流管理系统 电商技术揭秘五&#xff1a;电商平台的个性…...

多线程传参以及线程的优缺点

进程是资源分配的基本单位 线程是调度的基本单位 笼统来说&#xff0c;线程有以下优点&#xff1a; 创建一个新线程的代价要比创建一个新进程小得多 与进程之间的切换相比&#xff0c;线程之间的切换需要操作系统做的工作要少很多 线程占用的资源要比进程少很多 能充分利用多…...

keil创建单片机工程

一、创建工程 打开Keil uVision4&#xff0c;依次选择 Project—>New uVision4 Project&#xff0c;选择工程保存路径及填写工程名称&#xff0c;如下图 然后点“保存”。在Select a CPU Data Base File中选择"STC MCU Database"&#xff0c;点 "OK"&am…...

QT 串口助手 学习制作记录

QT 串口助手qt 学习制作记录 参考教程&#xff1a;​​​​​​QT初体验&#xff1a;手把手带你写一个自己的串口助手_qt设计串口助手的流程图-CSDN博客 Qt之串口编程&#xff08;添加QSerialPort模块&#xff09;_如何安装 qt串口模块教程-CSDN博客 串口调试助手&#xff1…...

Github 2024-04-13 Rust开源项目日报Top10

根据Github Trendings的统计,今日(2024-04-13统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Rust项目10CUE项目1Go项目1Tauri: 构建小型、快速和安全的桌面应用程序 创建周期:1673 天开发语言:Rust协议类型:Apache License 2.0Star数量…...

大模型日报|今日必读的10篇大模型论文

大家好&#xff0c;今日必读的大模型论文来啦&#xff01; 1.谷歌推出新型 Transformer 架构&#xff1a;反馈注意力就是工作记忆 虽然 Transformer 给深度学习带来了革命性的变化&#xff0c;但二次注意复杂性阻碍了其处理无限长输入的能力。 谷歌研究团队提出了一种新型 T…...

深度学习 Lecture 8 决策树

一、决策树模型&#xff08;Decision Tree Model) 椭圆形代表决策节点&#xff08;decison nodes)&#xff0c;矩形节点代表叶节点&#xff08;leaf nodes)&#xff0c;方向上的值代表属性的值&#xff0c; 构建决策树的学习过程&#xff1a; 第一步&#xff1a;决定在根节点…...

打包 docker 容器镜像到另一台电脑

# 提交容器为镜像 <container_id> 容器id my_migration_image 镜像名称 docker commit <container_id> my_migration_image # 保存镜像为tar文件 docker save my_migration_image > my_migration_image.tar 在另一台电脑上导入上面的镜像&#xff0c;请…...

贪心算法--购买股票

给你一个整数数组 prices &#xff0c;其中 prices[i] 表示某支股票第 i 天的价格。 在每一天&#xff0c;你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买&#xff0c;然后在 同一天 出售。 返回 你能获得的 最大 利润 。 示例 1&a…...

在Mac主机上连接Linux虚拟机

前言 最近醉心于研究Linux&#xff0c;于是在PD上安装了一个Debian Linux虚拟机&#xff0c;用来练练手。但是每次在mac和Linux之间切换很是麻烦&#xff0c;有没有一种方法&#xff0c;可以在mac终端直接连接我的虚拟机&#xff0c;这样在mac终端上就可以直接操控我的Linux虚…...

前端如何单独做虚拟奖金池?

公司业务需求要做一个虚拟奖金池&#xff0c;具体是需求是&#xff0c;不需要后端数据支持&#xff0c;但是又需要不同用户看到的奖金池数据每次变动都是一致的&#xff0c;并且要在给定的最小最大值中变动。 一开始看需求&#xff0c;因为需要所有登录/未登录&#xff0c;不同…...

Cursor实现用excel数据填充word模版的方法

cursor主页&#xff1a;https://www.cursor.com/ 任务目标&#xff1a;把excel格式的数据里的单元格&#xff0c;按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例&#xff0c;…...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

【Linux】Linux 系统默认的目录及作用说明

博主介绍&#xff1a;✌全网粉丝23W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能

1. 开发环境准备 ​​安装DevEco Studio 3.1​​&#xff1a; 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK ​​项目配置​​&#xff1a; // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...

鸿蒙(HarmonyOS5)实现跳一跳小游戏

下面我将介绍如何使用鸿蒙的ArkUI框架&#xff0c;实现一个简单的跳一跳小游戏。 1. 项目结构 src/main/ets/ ├── MainAbility │ ├── pages │ │ ├── Index.ets // 主页面 │ │ └── GamePage.ets // 游戏页面 │ └── model │ …...

门静脉高压——表现

一、门静脉高压表现 00:01 1. 门静脉构成 00:13 组成结构&#xff1a;由肠系膜上静脉和脾静脉汇合构成&#xff0c;是肝脏血液供应的主要来源。淤血后果&#xff1a;门静脉淤血会同时导致脾静脉和肠系膜上静脉淤血&#xff0c;引发后续系列症状。 2. 脾大和脾功能亢进 00:46 …...

js 设置3秒后执行

如何在JavaScript中延迟3秒执行操作 在JavaScript中&#xff0c;要设置一个操作在指定延迟后&#xff08;例如3秒&#xff09;执行&#xff0c;可以使用 setTimeout 函数。setTimeout 是JavaScript的核心计时器方法&#xff0c;它接受两个参数&#xff1a; 要执行的函数&…...

【记录坑点问题】IDEA运行:maven-resources-production:XX: OOM: Java heap space

问题&#xff1a;IDEA出现maven-resources-production:operation-service: java.lang.OutOfMemoryError: Java heap space 解决方案&#xff1a;将编译的堆内存增加一点 位置&#xff1a;设置setting-》构建菜单build-》编译器Complier...

新版NANO下载烧录过程

一、序言 搭建 Jetson 系列产品烧录系统的环境需要在电脑主机上安装 Ubuntu 系统。此处使用 18.04 LTS。 二、环境搭建 1、安装库 $ sudo apt-get install qemu-user-static$ sudo apt-get install python 搭建环境的过程需要这个应用库来将某些 NVIDIA 软件组件安装到 Je…...