当前位置: 首页 > 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;不同…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

Razor编程中@Html的方法使用大全

文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...

算法打卡第18天

从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 输入&#xff1a;inorder [9,3,15,20,7…...

ThreadLocal 源码

ThreadLocal 源码 此类提供线程局部变量。这些变量不同于它们的普通对应物&#xff0c;因为每个访问一个线程局部变量的线程&#xff08;通过其 get 或 set 方法&#xff09;都有自己独立初始化的变量副本。ThreadLocal 实例通常是类中的私有静态字段&#xff0c;这些类希望将…...

Linux入门课的思维导图

耗时两周&#xff0c;终于把慕课网上的Linux的基础入门课实操、总结完了&#xff01; 第一次以Blog的形式做学习记录&#xff0c;过程很有意思&#xff0c;但也很耗时。 课程时长5h&#xff0c;涉及到很多专有名词&#xff0c;要去逐个查找&#xff0c;以前接触过的概念因为时…...