本文源码:GitHub·点这里 || GitEE·点这里

一、生活场景

1、场景描述

电竞是游戏比赛达到“竞技”层面的体育项目。利用电子设备作为运动器械进行的、人与人之间的智力对抗运动。通过电竞,可以提高人的反应能力、协调能力、团队精神等。但是不同人群的对电竞的持有的观念不一样,有的人认为电竞就是沉迷网络,持反对态度,而有的人就比较赞同。下面基于访问者模式来描述该场景。

2、场景图解

3、代码实现

public class C01_InScene {public static void main(String[] args) {DataSet dataSet = new DataSet() ;dataSet.addCrowd(new Youth());dataSet.addCrowd(new MiddleAge());CrowdView crowdView = new Against() ;dataSet.display(crowdView);crowdView = new Approve() ;dataSet.display(crowdView);}
}
/*** 双分派,不同人群管理*/
abstract class Crowd {abstract void accept(CrowdView action);
}
class Youth extends Crowd {@Overridepublic void accept(CrowdView view) {view.getYouthView(this);}
}
class MiddleAge extends Crowd {@Overridepublic void accept(CrowdView view) {view.getMiddleAgeView (this);}
}
/*** 不同人群观念的管理*/
abstract class CrowdView {// 青年人观念abstract void getYouthView (Youth youth);// 中年人观念abstract void getMiddleAgeView (MiddleAge middleAge);
}
class Approve extends CrowdView {@Overridepublic void getYouthView(Youth youth) {System.out.println("青年人赞同电竞");}@Overridepublic void getMiddleAgeView(MiddleAge middleAge) {System.out.println("中年人赞同电竞");}
}
class Against extends CrowdView {@Overridepublic void getYouthView(Youth youth) {System.out.println("青年人反对电竞");}@Overridepublic void getMiddleAgeView(MiddleAge middleAge) {System.out.println("中年人反对电竞");}
}
/*** 提供一个数据集合*/
class DataSet {private List<Crowd> crowdList = new ArrayList<>();public void addCrowd (Crowd crowd) {crowdList.add(crowd);}public void display(CrowdView crowdView) {for(Crowd crowd : crowdList) {crowd.accept(crowdView);}}
}

二、访问者模式

1、基础概念

访问者模式是对象的行为模式,把作用于数据结构的各元素的操作封装,操作之间没有关联。可以在不改变数据结构的前提下定义作用于这些元素的不同的操作。主要将数据结构与数据操作分离,解决数据结构和操作耦合问题核心原理:被访问的类里面加对外提供接待访问者的接口。

2、模式图解

3、核心角色

  • 抽象访问者角色

声明多个方法操作,具体访问者角色需要实现的接口。

  • 具体访问者角色

实现抽象访问者所声明的接口,就是各个访问操作。

  • 抽象节点角色

声明接受操作,接受访问者对象作为参数。

  • 具体节点角色

实现抽象节点所规定的具体操作。

  • 结构对象角色

能枚举结构中的所有元素,可以提供一个高层的接口,用来允许访问者对象访问每一个元素。

4、源码实现

public class C02_Visitor {public static void main(String[] args) {ObjectStructure obs = new ObjectStructure();obs.add(new NodeA());obs.add(new NodeB());Visitor visitor = new VisitorA();obs.doAccept(visitor);}
}
/*** 抽象访问者角色*/
interface Visitor {/*** NodeA的访问操作*/void visit(NodeA node);/*** NodeB的访问操作*/void visit(NodeB node);
}
/*** 具体访问者角色*/
class VisitorA implements Visitor {@Overridepublic void visit(NodeA node) {node.operationA() ;}@Overridepublic void visit(NodeB node) {node.operationB() ;}
}
class VisitorB implements Visitor {@Overridepublic void visit(NodeA node) {node.operationA() ;}@Overridepublic void visit(NodeB node) {node.operationB() ;}
}
/*** 抽象节点角色*/
abstract class Node {/*** 接收访问者*/abstract void accept(Visitor visitor);
}
/*** 具体节点角色*/
class NodeA extends Node{@Overridepublic void accept(Visitor visitor) {visitor.visit(this);}public void operationA(){System.out.println("NodeA.operationA");}
}
class NodeB extends Node{@Overridepublic void accept(Visitor visitor) {visitor.visit(this);}public void operationB(){System.out.println("NodeB.operationB");}
}
/*** 结构对象角色类*/
class ObjectStructure {private List<Node> nodes = new ArrayList<>();public void detach(Node node) {nodes.remove(node);}public void add(Node node){nodes.add(node);}public void doAccept(Visitor visitor){for(Node node : nodes) {node.accept(visitor);}}
}

三、Spring框架应用

1、Bean结构的访问

BeanDefinitionVisitor类,遍历bean的各个属性;接口 BeanDefinition,定义Bean的各样信息,比如属性值、构造方法、参数等等。这里封装操作bean结构的相关方法,但却没有改变bean的结构。

2、核心代码块

public class BeanDefinitionVisitor {public void visitBeanDefinition(BeanDefinition beanDefinition) {this.visitParentName(beanDefinition);this.visitBeanClassName(beanDefinition);this.visitFactoryBeanName(beanDefinition);this.visitFactoryMethodName(beanDefinition);this.visitScope(beanDefinition);if (beanDefinition.hasPropertyValues()) {this.visitPropertyValues(beanDefinition.getPropertyValues());}if (beanDefinition.hasConstructorArgumentValues()) {ConstructorArgumentValues cas = beanDefinition.getConstructorArgumentValues();this.visitIndexedArgumentValues(cas.getIndexedArgumentValues());this.visitGenericArgumentValues(cas.getGenericArgumentValues());}}
}

四、模式总结

1、优点描述

(1) 访问者模式符合单一职责原则、使程序具有良好的扩展性、灵活性;

(2) 访问者模式适用与拦截器与过滤器等常见功能,数据结构相对稳定的场景;

2、缺点描述

(1) 访问者关注其他类的内部细节,依赖性强,违反迪米特法则,这样导致具体元素更新麻烦;

(2) 访问者依赖具体元素,不是抽象元素,面向细节编程,违背依赖倒转原则;

五、源代码地址

GitHub·地址
https://github.com/cicadasmile/model-arithmetic-parent
GitEE·地址
https://gitee.com/cicadasmile/model-arithmetic-parent

Java描述设计模式(23):访问者模式相关推荐

  1. [设计模式] 23 访问者模式 visitor Pattern

    在GOF的<设计模式:可复用面向对象软件的基础>一书中对访问者模式是这样说的:表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作.访问 ...

  2. C++设计模式23——访问者模式

    https://blog.csdn.net/CoderAldrich/article/details/83270301 访问者模式 在GOF的<设计模式:可复用面向对象软件的基础>一书中对 ...

  3. java的string访问某个元素_C#深究.net常用的23种设计模式之访问者模式(Vistor Pattern)...

    一.引言 在上一篇博文中分享了责任链模式,责任链模式主要应用在系统中的某些功能需要多个对象参与才能完成的场景.在这篇博文中,我将为大家分享我对访问者模式的理解. 二.访问者模式介绍 2.1 访问者模式 ...

  4. 在王者荣耀角度下分析面向对象程序设计B中23种设计模式之访问者模式

    · 访问者模式在王者荣耀中的应用 · 一.简述 在王者荣耀的社交系统中有2大核心,一为好友系统二为战队系统,好友系统偏向于个人,战队系统偏向于一个集体.玩家可以自己筹备创建战队.亦可加入其他战队.战队 ...

  5. Java设计模式(访问者模式-迭代器模式-观察者模式-中介者模式)

    Java设计模式Ⅶ 1.访问者模式 1.1 访问者模式概述 1.2 代码理解 2.迭代器模式 2.1 迭代器模式概述 2.2 代码理解 3.观察者模式 3.1 观察者模式概述 3.2 代码理解 4.中 ...

  6. Java描述设计模式(05):原型模式

    一.原型模式简介 1.基础概念 原型模式属于对象的创建模式.通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象. 2.模式结构 原型模式要求对象实现一个 ...

  7. C#设计模式(22)——访问者模式(Vistor Pattern)

    一.引言 在上一篇博文中分享了责任链模式,责任链模式主要应用在系统中的某些功能需要多个对象参与才能完成的场景.在这篇博文中,我将为大家分享我对访问者模式的理解. 二.访问者模式介绍 2.1 访问者模式 ...

  8. 初学Java常用设计模式之——原型模式

    声明:转载请附上原文链接 提示:标题序号从3开始,是照应不同设计模式笔记发布的顺序而定的,比如,第上一篇文章 初学Java常用设计模式之--工厂模式 序号从2开始. 标题后面之所以加上了解,是因为相对 ...

  9. 北风设计模式课程---访问者模式(Visitor)

    北风设计模式课程---访问者模式(Visitor) 一.总结 一句话总结: 设计模式是日常问题的经验总结方案,所以学好设计模式对日常出现的问题可以有很好的解决. 访问者设计模式有点神似 抽象工厂模式, ...

最新文章

  1. matlab 摄像头拍照,matlab摄像头拍照
  2. RDKit | 基于SSSR区分环状化合物和链状化合物
  3. AI:2020年6月21日北京智源大会演讲分享之20:00-21:00邱锡鹏教授《如何学习深度学习》
  4. java在SAE中使用的相关问题总结
  5. SQL性能优化整合持续更新
  6. 1.x和2.x的区别
  7. 启动多个线程后同时并行执行程序
  8. 唤醒锁: 检测 Android* 应用中的 No-Sleep(无法进入睡眠)问题
  9. C#之判断Mysql数据库是否存在
  10. oracle 常用索引分析,使用原则和注意事项
  11. Mac Android studio: Gradle Build Running 、 run build 运行卡顿 、 加载慢问题问题(亲测可用)
  12. java因子分析_spss因子分析
  13. eureka 缺点
  14. 数学用计算机开方,开方(数学术语)_百度百科
  15. 一只公鸡5块钱,一只母鸡3块钱,3只小鸡一块钱,一个农夫用100块钱买100只鸡(不许解方程),怎么实现?编写java程序。...
  16. 电商宝打单发货-菜鸟面单回收
  17. 极简效率指南:数据分析师如何高效工作和提升自己
  18. 力扣46.全排列(回溯法)
  19. Ubuntu 怎么在 Libreoffice 中添加字体
  20. 共识协议(5)DPOS委托权益证明

热门文章

  1. linux下使用tc工具模拟网络延迟和丢包
  2. 操作系统之进程管理:3、进程控制(进程状态转化的实现)、原语、进程通信(共享、管道、消息)
  3. Python数据结构:序列(列表[]、元组())与映射(字典{})语法总结
  4. 处理大并发之四 libevent demo详细分析(对比epoll)
  5. qt setData()和data()
  6. C/C++ 进程的探索(fork函数)
  7. Oracle数据库导入导出 imp/exp备份还原
  8. Mysql索引介绍及常见索引的区别
  9. 【一周读书】哲学家,你们都干了些什么?
  10. Java-排序算法-冒泡排序