在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作。主要解决稳定的数据结构和易变的操作耦合问题。

大话设计模式中程杰老师给出的定义是,访问者模式:表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作

访问者模式结构图:

基本代码:

package com.visitor;
/*** Visitor类,为该对象结构中的ConcreteElement的每一个实现类声明一个visit操作* @author LMB**/
public abstract class Visitor {public abstract void visitConcreteElementA(ConcreteElementA concreteElementA);public abstract void visitConcreteElementB(ConcreteElementB concreteElementB);}
package com.visitor;
/*** 具体访问者ConcreteVisitorA,实现每个由Visitor声明的操作。每个操作实现算法的一部分,而该算法* 乃是对应于结构中对象的类* @author LMB**/
public class ConcreteVisitorA extends Visitor {@Overridepublic void visitConcreteElementA(ConcreteElementA concreteElementA) {System.out.println(concreteElementA.getClass() + "被" + this.getClass() + "访问");     }@Overridepublic void visitConcreteElementB(ConcreteElementB concreteElementB) {System.out.println(concreteElementB.getClass() + "被" + this.getClass() + "访问");         }}
package com.visitor;
/*** 具体访问者ConcreteVisitorB,实现每个由Visitor声明的操作。每个操作实现算法的一部分,而该算法* 乃是对应于结构中对象的类* @author LMB**/
public class ConcreteVisitorB extends Visitor {@Overridepublic void visitConcreteElementA(ConcreteElementA concreteElementA) {System.out.println(concreteElementA.getClass() + "被" + this.getClass() + "访问");     }@Overridepublic void visitConcreteElementB(ConcreteElementB concreteElementB) {System.out.println(concreteElementB.getClass() + "被" + this.getClass() + "访问");         }}
package com.visitor;public abstract class Element {public abstract void accept(Visitor visitor);}
package com.visitor;
/*** 具体元素对象ConcreteElementA,实现接受访问者访问的accept()方法* @author LMB**/
public class ConcreteElementA extends Element {@Overridepublic void accept(Visitor visitor) {visitor.visitConcreteElementA(this);        }//其它相关方法public void operationA(){}}
package com.visitor;
/*** 具体元素对象ConcreteElementB,实现接受访问者访问的accept()方法* @author LMB**/
public class ConcreteElementB extends Element {@Overridepublic void accept(Visitor visitor) {visitor.visitConcreteElementB(this);        }//其它相关方法public void operationB(){}}
package com.visitor;import java.util.ArrayList;
import java.util.List;
/*** ObjectStructure类,能每句它的元素,可以提供一个高层的接口以允许访问者访问它的元素* @author LMB**/
public class ObjectStructure {private List<Element> elements = new ArrayList<Element>();//添加元素public void attach(Element element){elements.add(element);}//移除元素public void detach(Element element){elements.remove(element);}//元素接受访问者访问public void accept(Visitor visitor){for (Element e : elements) {e.accept(visitor);}}}
package com.visitor;public class VisitorPatternDemo {public static void main(String[] args) {ObjectStructure objectStructure = new ObjectStructure();//将需要被访问的element实例添加到数据结构ObjectStructure中objectStructure.attach(new ConcreteElementA());objectStructure.attach(new ConcreteElementB());ConcreteVisitorA concreteVisitorA = new ConcreteVisitorA();ConcreteVisitorB concreteVisitorB = new ConcreteVisitorB();//element接受访问者的访问objectStructure.accept(concreteVisitorA);objectStructure.accept(concreteVisitorB);}}

运行结果:

以上的模式定义中,我们只列出了两种Element的实现,如果Element的实现不止这两种,而是可以有多种ConcreteElementA、ConcreteElementB、ConcreteElementC……,那就意味着Visitor类中的抽象方法就不可能稳定了,每增加一种Element实现就需要在Visitor类和它所有的实现类中都增加一个访问方法,这就不符合开放-封闭原则了。

由此,我们可以抽象出访问者模式的适用范围(使用场景)

1、访问者模式把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由地演化,所以适用于数据结构相对稳定的操作

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

3、需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作”污染”这些对象的类,也不希望在增加新操作时修改这些类。

优点:

访问者模式的优点是增加新的操作很容易,因为增加新的操作就意味着增加一个新的访问者。访问者模式将有关的行为集中到一个访问者对象中。

缺点:

使增加新的数据结构变得困难。

大话设计模式—访问者模式相关推荐

  1. linkin大话设计模式--常用模式总结

    linkin大话设计模式--常用模式总结 一,常用设计模式定义 Abstract Factory(抽象工厂模式):提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. Adapter( ...

  2. 设计模式 访问者模式

    文章目录 访问者模式 访问者模式实战 访问者模式 在相同的数据结构下, 增加容易变化的业务访问逻辑, 为了增强扩展性, 将易变的访问逻辑进行解耦的一种设计模式. 访问者模式实战 模拟学校中, 有老师和 ...

  3. 设计模式---访问者模式

    访问者模式 介绍 定义及使用场景 UML类图 角色 财务案例 个人心得体会 静态分派以及动态分派 静态分派 动态分派 访问者模式中的伪动态双分派 对访问者模式的一些思考 总结 优点 缺点 适用性 参考 ...

  4. linkin大话设计模式--桥接模式

    linkin大话设计模式--桥接模式 桥接模式是一种结构化模式,他主要应对的是:由于实际的需要,某个类具有2个或者2个以上维度的变化,如果只是使用继承将无法实现功能,或者会使得设计变得相当的臃肿.我们 ...

  5. linkin大话设计模式--模板方法模式

    linkin大话设计模式--模板方法模式 准备一个抽象类,将部分逻辑以具体方法的形式实现,然后申明一些抽象方法来迫使子类实现剩余的逻辑.不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不 ...

  6. C++设计模式——访问者模式(visitor pattern)

    一.原理讲解 1.1意图 表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作. 1.2应用场景 一个对象结构包含很多类对象,它们有不同的接口,而你 ...

  7. C++设计模式-访问者模式

    目录 基本概念 代码与实例 基本概念 访问者模式(Visitor):表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变元素的类的前提下定义作用于这些元素的新操作. UML图如下(此图来源于大 ...

  8. PHP设计模式——访问者模式

    声明:本系列博客参考资料<大话设计模式>,作者程杰. 访问者模式表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作. UML类图: 角色 ...

  9. java设计模式---访问者模式

      Java深入到一定程度,就不可避免的碰到设计模式这一概念,了解设计模式,将使自 己对java中的接口或抽象类应用有更深的理解.设计模式在java的中型系统中应用广 泛,遵循一定的编程模式,才能使自 ...

最新文章

  1. BusinessObject Port 配置
  2. 【ABAP】文本表查找
  3. 【收藏】Win10自带的邮件客户端配置腾讯企业邮箱账号详解
  4. bzoj 2844: albus就是要第一个出场 高斯消元
  5. 「技术人生」:技术同学应该如何理解业务?
  6. 从技术角度聊聊,短视频为何让人停不下来?
  7. c语言圈子,C语言经典编程
  8. Leetcode题库 144.二叉树的前序遍历(递归 C实现)
  9. [ZOJ 4024] Peak
  10. 二进制编译安装mysql_数据库(MySQL)二进制安装+编译安装 + MariaDB编译安装
  11. LeetCode 1829. 每个查询的最大异或值(前缀异或 + 位运算)
  12. python判断set里是否包含值_【python】判断值是否在list和set的对比以及set的实现原理...
  13. 力扣题目系列:121. 买卖股票的最佳时机
  14. Codeforces1037G A Game on Strings 【SG函数】【区间DP】
  15. CGPathAddArc
  16. 自然语言处理-停用词
  17. 同步时钟配置电脑自动校时
  18. iOS App 性能优化总结
  19. 蓝牙技术|蓝牙Mesh照明技术照亮世界
  20. [Android系统开发]Launcher Hotseat图标居中排列

热门文章

  1. 野蔷薇的伤感人生日志:已失落于尘埃,再也找寻不得
  2. 树莓派can总线_RPi 2B: CAN总线通信 - 通过OBD-II接口获取车辆信息
  3. 在美国成年人群体中,语音助手Siri已经成了第二大移动搜索引擎
  4. Respones请求重定向
  5. php从一个字符串中过滤掉英文,php过滤只保留中文,英文以及数字的方法
  6. 计算机24游戏怎么玩,外媒评24款史上最好玩的策略游戏 投身宏伟场景玩到爆
  7. 谈谈登录注册的如何实现
  8. 天盾linux数据恢复,天盾Mac数据恢复软件
  9. 天津发票版本文件服务器端口,天津增值税发票综合服务平台入口
  10. 编译原理中的first集,follow集和selec集的小解