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

设计模式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.xdnf.cn/news/688717.html

相关文章:

  • 【AUTOSAR OS】 保护功能解析:从原理到应用与源代码解析(下篇)
  • 《Python+AI如何颠覆传统文书审查模式》
  • 【网络安全】——Modbus协议详解:工业通信的“通用语言”
  • JS 逆向太费劲,试试 JS 注入!
  • 服务器上用脚本跑python深度学习的注意事项(ubantu系统)
  • 【第2章 绘制】2.6 阴影
  • 基于stm32LORA无线抄表系统仿真
  • 人工智能在智能建筑中的创新应用与未来趋势
  • 将docker容器保存为镜像,让后将镜像打包保存到本地
  • WPF的基础控件:布局控件(StackPanel DockPanel)
  • React+Antd全局加载遮罩工具
  • 2. 数据结构基本概念 (2)
  • LLM 对齐新范式:深入解析 DPO (Direct Preference Optimization) 的原理与实践
  • Microsoft的在word中选择文档中的所有表格进行字体和格式的调整时的解决方案
  • 180 度 = π 弧度
  • 2025吉林ccpc【部分题解】
  • c++第三天(对象与构造函数)
  • ICDMC 2025:创新媒体模式,迎接数字时代的挑战
  • Redission学习专栏(一):快速入门及核心API实践
  • CORS跨域资源共享解析
  • 算法刷题记录:滑动窗口经典题目解析
  • 【大模型原理与技术-毛玉仁】第三章 Prompt工程
  • web-css
  • 20250528-C#知识:函数简介及函数重载
  • 外部访问可视化监控 Grafana (Windows版本)
  • 扇形 圆形 面积公式
  • 如何在WordPress中选择最佳Elementor主题:专家指南
  • 前端大文件上传-断点续传
  • 影刀RPA-17- 列表练习
  • 使用 Shell 脚本实现 Spring Boot 项目自动化部署到 Docker(Ubuntu 服务器)