java的visitor模式_java设计模式(二十一)访问者模式(Visitor)

介绍

访问者模式(Visitor Pattern):表示一个作用于某对象结构中的各元素的操作,它使我们可以在不改变各元素的类的前提下定义作用于这些元素的新操作。访问者模式是一种对象行为型模式。

简单来说,访问者模式就是一种分离对象数据结构与行为的方法,通过这种分离,可达到为一个被访问者动态添加新的操作而无需做其它的修改的效果。

关系图:

831c223fe76f4cbcdba5e54ff8fc18c2.png

Visitor接口:存放要访问的对象1

2

3public interface{

public void visit(Subject sub);

}

实现类:1

2

3

4

5

6public class MyVisitor implements{

public void visit(Subject sub){

System.out.println("visit the subject:"+sub.getSubject());

}

}

Subject接口:accept方法,接受将要访问它的对象,getSubject()获取将要被访问的属性1

2

3

4public interface Subject{

public void accept(Visitor visitor);

public String getSubject();

}

实现类:1

2

3

4

5

6

7

8

9

10

11public class MySubject implements Subject{

public void accept(Visitor visitor){

visitor.visit(this);

}

public String getSubject(){

return "love";

}

}

测试类:1

2

3

4

5

6

7

8public class Test{

public static void main(String[] args){

Visitor visitor = new MyVisitor();

Subject sub = new MySubject();

sub.accept(visitor);

}

}

该模式适用场景:如果我们想为一个现有的类增加新功能,不得不考虑几个事情:新功能会不会与现有功能出现兼容性问题?

以后会不会再需要添加?

如果类不允许修改代码怎么办?

面对这些问题,最好的解决方法就是使用访问者模式,访问者模式适用于数据结构相对稳定的系统,把数据结构和算法解耦

扩展

1. 模式动机在实际使用时,对同一集合对象的操作并不是唯一的,对相同的元素对象可能存在多种不同的操作方式。而且这些操作方式并不稳定,可能还需要增加新的操作,以满足新的业务需求。此时,访问者模式就是一个值得考虑的解决方案。

访问者模式的目的是封装一些施加于某种数据结构元素之上的操作,一旦这些操作需要修改的话,接受这个操作的数据结构可以保持不变。为不同类型的元素提供多种访问操作方式,且可以在不修改原有系统的情况下增加新的操作方式。

2. 模式结构

f89069009a08555f9acf441f6256cc6b.png

访问者模式包含如下角色:Vistor: 抽象访问者

ConcreteVisitor: 具体访问者

Element: 抽象元素

ConcreteElement: 具体元素

ObjectStructure: 对象结构

3. 模式分析访问者模式中对象结构存储了不同类型的元素对象,以供不同访问者访问。

访问者模式包括两个层次结构,一个是访问者层次结构,提供了抽象访问者和具体访问者,一个是元素层次结构,提供了抽象元素和具体元素。

相同的访问者可以以不同的方式访问不同的元素,相同的元素可以接受不同访问者以不同访问方式访问。在访问者模式中,增加新的访问者无须修改原有系统,系统具有较好的可扩展性

典型的抽象访问者类代码:1

2

3

4

5

6

7public abstract class{

public abstract void visit(ConcreteElementA elementA);

public abstract void visit(ConcreteElementB elementB);

public void visit(ConcreteElementC elementC){

//元素ConcreteElementC操作代码

}

}

典型的具体访问者类代码:1

2

3

4

5

6

7

8public class ConcreteVisitor extends{

public void visit(ConcreteElementA elementA){

//元素ConcreteElementA操作代码

}

public void visit(ConcreteElementB elementB){

//元素ConcreteElementB操作代码

}

}

典型的抽象元素类代码:1

2

3public interface Element{

public void accept(Visitor visitor);

}

具体元素类代码:1

2

3

4

5

6

7

8

9public class ConcreteElementA implements Element{

public void accept(Visitor visitor){

visitor.visit(this);

}

public void operationA(){

//业务方法

}

}

典型的对象结构类代码:1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16public class ObjectStructure{

private ArrayList list=new ArrayList();

public void accept(Visitor visitor){

Iterator i=list.iterator();

while(i.hasNext()) {

((Element)i.next()).accept(visitor);

}

}

public void addElement(Element element){

list.add(element);

}

public void removeElement(Element element){

list.remove(element);

}

}

4. 适用场景一个对象结构包含很多类型的对象,希望对这些对象实施一些依赖其具体类型的操作。在访问者中针对每一种具体的类型都提供了一个访问操作,不同类型的对象可以有不同的访问操作。

需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作污染这些对象的类,也不希望在增加新操作时修改这些类。访问者模式使得我们可以将相关的访问操作集中起来定义在访问者类中,对象结构可以被多个不同的访问者类所使用,将对象本身与对象的访问操作分离。

对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。

5. 模式应用在一些编译器的设计中运用了访问者模式,程序代码是被访问的对象,它包括变量定义、变量赋值、逻辑运算、算术运算等语句,编译器需要对代码进行分析,如检查变量是否定义、变量是否赋值、算术运算是否合法等,可以将不同的操作封装在不同的类中,如检查变量定义的类、检查变量赋值的类、检查算术运算是否合法的类,这些类就是具体访问者,可以访问程序代码中不同类型的语句。在编译过程中除了代码分析外,还包含代码优化、空间分配和代码生成等部分,也可以将每一个不同编译阶段的操作封装到了跟该阶段有关的一个访问者类中。

在常用的Java XML处理技术DOM4J中,可以通过访问者模式的方式来读取并解析XML文档,VisitorSupport是DOM4J提供的Visitor接口的默认适配器,具体访问者只需继承VisitorSupport类即可。1

2

3

4

5

6

7

8public class MyVisitor extends VisitorSupport{

public void visit(Element element){

System.out.println(element.getName());

}

public void visit(Attribute attr){

System.out.println(attr.getName());

}

}

6. 模式扩展与其他模式联用由于访问者模式需要对对象结构进行操作,而对象结构本身是一个元素对象的集合,因此访问者模式经常需要与迭代器模式联用,在对象结构中使用迭代器来遍历元素对象。

在访问者模式中,元素对象可能存在容器对象和叶子对象,因此可以结合组合模式来进行设计。

访问者模式以一种倾斜的方式支持开闭原则,增加新的访问者方便,但是增加新的元素很困难。

7. 模式优缺点优点使得增加新的访问操作变得很容易。

将有关元素对象的访问行为集中到一个访问者对象中,而不是分散到一个个的元素类中。

可以跨过类的等级结构访问属于不同的等级结构的元素类。

让用户能够在不修改现有类层次结构的情况下,定义该类层次结构的操作。

缺点增加新的元素类很困难。在访问者模式中,每增加一个新的元素类都意味着要在抽象访问者角色中增加一个新的抽象操作,并在每一个具体访问者类中增加相应的具体操作,违背了开闭原则的要求。

破坏封装。访问者模式要求访问者对象访问并调用每一个元素对象的操作,这意味着元素对象有时候必须暴露一些自己的内部操作和内部状态,否则无法供访问者访问。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/551384.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

testlink mysql配置_TestLink安装配置手册

TestLink安装配置手册范围本文仅作为安装和配置TestLink的参考文档。本文的第一部分为TestLink的安装步骤,第二部分是TestLink的配置方法。本文和其他相关文档可在中寻求帮助一般TestLink安装的步骤如下:1.下载TestLink2.解压文件3.创建数据库4.导入缺省…

java mvc建包结构_Java SSM框架的配置方法、MVC结构的分析、响应的流程

今天头一次配置成功一个SSM框架,兴奋之余,还应该从使用的角度,将整个ssm配置的方法,配置的原因,认真的分析一下。在结束了对SSM框架简单的分析之后,就要开始回归基础,全面的认真复习。所以这个文…

英特尔显示器音频_英特尔也玩马甲?有关USB TypeC的冷知识你了解多少

随着Type-C接口的不断发展,这个接口也成为越来越多设备的标配,除了出现在手机、平板电脑和笔记本电脑等移动设备上,显卡这样的设备也开始配备Type-C接口了,本周末,小编为大家收集了一些有关Type-C接口的冷知识&#xf…

如何允许网页中的编辑器访问剪切板_Vditor下一代的 Markdown 编辑器,为未来而构建...

❝Vditor 是一款浏览器端的 Markdown 编辑器,支持所见即所得(富文本)、即时渲染(类似 Typora)和分屏预览模式。它使用 TypeScript 实现,支持原生 JavaScript、Vue、React、Angular,提供桌面版❞Markdown背景随着 Markdown 排版方式的普及&…

mpython掌控板作品_第1课 Arduino micro:bit 掌控板 创客教育常用的3类主控板

有很多朋友想学习创客,问我怎么学习。我建议他先百度一下“创客”,看看有什么感觉。结果还是很懵,五花八门,什么都有,找不到核心。简单理解,就是以前讲的DIY,自己动手,制作一个东西。…

redis启动没反应_Promethues如何针对Redis进行监控

需求:采用redis_exporter 收集数据,promethus采集redis_exporter数据,granfana展示数据一、简易安装redisyum install -y redisrpm -qa |grep redislsof -i :6379rpm -ql redissystemctl start redis找到配置文件/etc/redis.conf,修改 requir…

springboot整合rocketmq_面试官:简单说一下RocketMQ整合SpringBoot吧

前言在使用SpringBoot的starter集成包时,要特别注意版本。因为SpringBoot集成RocketMQ的starter依赖是由Spring社区提供的,目前正在快速迭代的过程当中,不同版本之间的差距非常大,甚至基础的底层对象都会经常有改动。例如如果使用…

java面试常考_JAVA面试常考系列十

JAVA面试常考系列十题目一Servlet是什么?Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,是用Java编写的服务器端程序,主要的作用是处理客户端请求并生成动态Web内容。一般情况下,Servlet主要…

的ui在vs中显示没有成员_在电脑桌面使用敬业签团队便签怎么设置新增内容在上面显示?...

实时跟进小组成员的各项任务的完成情况,及时将工作任务安排下去,是提高团队工作效率的较为有效的方法。在监督小组成员任务状况以及及时安排工作方面,选择一款支持多人同步在线协作的软件是非常有必要的。敬业签团队便签是一款不受系统、设备…

多表关联查询_【函数007】 EXCEL多表关联查询实战

继续函数实战系列教程,今天要分享的案例是根据填写的表名自动提取对应表中的数据数据准备:需求说明:我们希望实现,我们选择不同月份,显示对应月份表中的数据!处理方案:1、构建下拉列表(菜单)数据…

管理动物园动物c++_《过山车大亨》开发商公开新作 建立自己的动物园

知名模拟经营游戏开发商Frontier Developments近日宣布,旗下游戏《动物园之星》(Planet Zoo)即将在不久后发售,登录Steam平台。本座是一款模拟经营游戏,玩家在游戏中将会从零开始,建立一个属于自己的动物园世界。游戏中有多种不同…

安费诺amphenol连接器_安费诺的Ellison谈信号完整性职业和他的免费开源PCB设计软??件...

Amphenol的信号完整性工程师杰森埃里森(Jason Ellison )Amphenol(安费诺) ICC的高级职员信号完整性工程师杰森埃里森(Jason Ellison )深入了解了网络,给予EE(电子)社区以及他的开源信号完整性项目的重要性。信号完整性工程与其他EE(电子)领域相比如何?他…

mysql的contains_mysql中json_contains、json_extract等json查询方法的使用

新版 Mysql 中加入了对 JSON Document 的支持,可以创建 JSON 类型的字段,并有一套函数支持对JSON的查询、修改等操作。JSON是一种轻量级的数据交换格式,采用了独立于语言的文本格式,类似XML,但是比XML简单,…

260多媒体语言如何调节_260马力配9.7米货厢,实拍柳汽H5小三轴载货车

【卡车之家 原创】高速公路按轴的收费实施让9米6大单桥载货车火了起来,能够满足快递快运、电商物流等以方量为主的轻型货物运输。但这种大单桥18吨的限重对于不少卡友来说或许不太够用,而8x4载货车又有些大材小用了。这时,处于中间位置的三轴…

linux php 如何上传webshell,linux+apache+php的一次拿webshell的心得

首先俺先声明俺是个菜鸟,俺虽然是菜鸟但俺不会一直是菜鸟的(一旁兄弟喊到:别俺,俺,俺的,说普通话!)。俺,不对,我一直遵照着实践是检验真理的唯一标准这句话学习技术,这不…

织梦php重新安装教程,织梦CMS系统后台重装的操作教程

原标题:织梦CMS系统后台重装的操作教程网站在线运行,不可能一点问题都不存在,或者当初的网站设计、架构、功能已经不能满足现在用户的需求,所以我们会对网站做出相应的改动。网站除了前端的改版,还会有后台系统重装、服…

mpu9250姿态融合算法_基于投票方式的机器人装配姿态估计

作者:仲夏夜之星来源:公众号 3D视觉工坊链接:基于投票方式的机器人装配姿态估计论文题目:《Voting-Based Pose Estimation for Robotic Assembly Using a 3D Sensor》这篇文章被发表在2012年的IEEE International Conference on R…

skywalking原理_微服务链路追踪原理

作者:平也来源:关爱程序员社区背景介绍在微服务横行的时代,服务化思维逐渐成为了程序员的基本思维模式,但是,由于绝大部分项目只是一味地增加服务,并没有对其妥善管理,当接口出现问题时&#xf…

文本分析软件_读书笔记:伍多库卡茨质性文本分析:方法、实践与软件使用指南...

读书笔记:伍多库卡茨《质性文本分析:方法、实践与软件使用指南》一、这篇文章、这本书或这篇论文的中心思想、核心观点是什么?核心观点:质性数据如何系统化分析?三大主要方法:主题分析、评估分析和类型建构…

matlab两轮自平衡小车,两轮自平衡小车(全部设计资料+设计分析)

自己做的自平衡小车,基本达到预期效果。制作资料在压缩包里面,供参考。该两轮自平衡小车硬件设计概述:控制器:ATmega16;8MHz;加速度传感器:MMA2260;陀螺仪:EWTS82&#x…