介绍

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

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

关系图:

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. 模式结构

访问者模式包含如下角色: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. 模式优缺点优点使得增加新的访问操作变得很容易。

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

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

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

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

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

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

  1. java计数器策略模式_java设计模式(二十一)--策略模式

    对于策略模式,我在很多面试题上看到过考察这一类的问题,这种模式也的确比较好用. 我感觉这种模式就是将不同实现的方法放到一个接口中,然后通过实现这个接口来实现不同的运行结果,这种模式有三部分构成: 策略 ...

  2. C#设计模式之二十一访问者模式(Visitor Pattern)【行为型】

    一.引言 今天我们开始讲"行为型"设计模式的第九个模式,该模式是[访问者模式],英文名称是:Visitor Pattern.如果按老规矩,先从名称上来看看这个模式,我根本不能获得任 ...

  3. java的简单工厂模式_java设计模式之简单工厂模式

    简单工厂模式的概念 就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建.简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例. ...

  4. java 外观模式_Java设计模式11:外观模式

    外观模式 外观模式是对象的结构模式,外部与一个子系统的通信必须通过一个统一的外观对象进行.外观模式是一个高层次的接口,使得子系统更易于使用. 医院的例子 现代的软件系统都是比较复杂的.假如把医院比作一 ...

  5. java 桥接模式_JAVA设计模式之【桥接模式】

    桥接模式 蜡笔中颜色和型号之间存在耦合 毛笔中,颜色和型号解耦了 如果软件系统中某个类存在两个独立变化的维度,桥接模式可以将两个维度分离出来 角色 抽象类 扩充抽象类 实现类接口 提供基本操作 抽象类 ...

  6. 【白话设计模式二】外观模式(Facade)

    为什么80%的码农都做不了架构师?>>>    #0 系列目录# 白话设计模式 工厂模式 单例模式 [白话设计模式一]简单工厂模式(Simple Factory) [白话设计模式二] ...

  7. 设计模式学习之访问者模式(Visitor,行为型模式)(21)

    参考:https://www.cnblogs.com/edisonchou/p/7247990.html 在患者就医时,医生会根据病情开具处方单,很多医院都会存在以下这个流程:划价人员拿到处方单之后根 ...

  8. Java描述设计模式(23):访问者模式

    本文源码:GitHub·点这里 || GitEE·点这里 一.生活场景 1.场景描述 电竞是游戏比赛达到"竞技"层面的体育项目.利用电子设备作为运动器械进行的.人与人之间的智力对抗 ...

  9. (二十二)访问者模式详解(伪动态双分派) - 转

    作者:zuoxiaolong8810(左潇龙),转载请注明出处. 本次LZ和各位分享一下访问者模式,从场景.设计初衷以及实现方面来说,访问者模式算是LZ即将写到的24种设计模式当中,最复杂也是最难理解 ...

最新文章

  1. 分享五款java学习辅助工具,总有你用的上的~
  2. OpenWRT的ROM固件内置软件包修改与定制
  3. java网络编程(五)
  4. cuba 平台_CUBA 7的新功能
  5. 【课题总结】OpenCV 抠图项目实战(4)固定阈值抠图
  6. vue 指令 v-on 事件修饰符-自定义键盘事件
  7. Android视频播放
  8. python 编写一个函数来验证输入的字符串是否是有效的 IPv4 或 IPv6 地址_[LeetCode] 468. 验证IP地址
  9. 关于NTFS文件夹的安全权限分配的一些总结
  10. 万用表测线路断点位置_万用表测电流口诀,正确使用方法
  11. c语言作业百万富翁for循环做,c语言例题(c语言经典例题100道pdf)
  12. WP7手机Zune官方升级教程
  13. 三菱f800变频器 频率设定_三菱F800变频器调试参数总结.docx
  14. iPhone5s 换电池、修右上角翘起的悲催过程
  15. 如何巧妙应用shift键的解说
  16. OutMan——单例模式、代理模式以及iOS沙盒(sandbox)机制
  17. ml-agents与tensorflow结合的先关操作文档
  18. shell 分割文本_shell教程(2):积木游戏之认识积木--重要的系统命令
  19. 【引用】pygame菜鸟入门指南
  20. 了解到的生二孩最好的理由

热门文章

  1. 有人问我,为什么1+1等于2
  2. PingingLab传世经典系列《CCNA完全配置宝典》-2.7 EIGRP基本配置
  3. MRI骨水肿是早期未分化关节炎演变为RA的独立预测预测因素
  4. math 向上取整_自我说明:关于Math和File类的具体说明.
  5. python 怎么表示sqlserver null_如何使用Python将sqlserver查询输出写入.txt文件?
  6. linux中断处理模式,Linux在保护模式下的中断处理分析.pdf
  7. php 读文件返回字符串,PHP:file_get_contents('php:// input')返回JSON消息的字符串...
  8. 探测器反向偏压_近红外和可见光双模有机光电探测器
  9. flux java_Java反应式框架Reactor中的Mono和Flux
  10. django css_在应用程序上实现CSS Django的