当前位置: 首页 > 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可以直接运行。

如果觉得本文还不错,就请点个赞给作者一点鼓励吧!如果有建议,也请评论指教和讨论!

相关文章:

  • Flutter 与 Android 原生布局组件对照表(完整版)
  • HTTP协议接口三种测试方法之-JMeter(保姆教程)
  • GO——内存逃逸分析
  • goofys挂载minio为本地目录
  • IAR创建STM8裸机工程创建---STM8开发【二】
  • 金融全业务场景的系统分层与微服务域架构切分
  • 科技赋能音乐,指北科技新品闪耀广州国际乐器展
  • 智慧场馆:科技赋能的艺术盛宴
  • 青岛市长任刚与深兰科技董事长陈海波会谈,深兰青岛项目即将进入快车道!
  • leetcode hot100刷题日记——24.回文链表
  • Problem H. saki 酱 saki 酱 saki 酱 saki 酱(树的直径)
  • 影刀RPA-17- 列表练习
  • OpenCV CUDA模块直方图计算------在 GPU上执行直方图均衡化(Histogram Equalization)函数equalizeHist
  • 【Redis】基本命令
  • 油桃TV v20250519 一款电视端应用网站聚合TV播放器 支持安卓4.1
  • 英飞凌SBC芯片TLE9263QX for STM32的库函数与使用
  • git push Git远端意外挂断
  • 基于FPGA的DES加解密系统verilog实现,包含testbench和开发板硬件测试
  • AI笔记 - 模型调试 - 调试方式
  • 基于ssm的商城系统(全套)
  • 秦皇岛黄金海岸收费吗/青岛百度关键词优化
  • 怎么可以找到做公益的网站/宁波seo快速优化课程
  • 建立个人网站的详细步骤/推广普通话宣传周活动方案
  • 模块化网站建设 局域网/建设营销网站
  • 重庆做模块网站/百度app下载官方免费下载最新版
  • 珠海网站制作服务/企业网站优化服务公司