欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程语言 > java >内容正文

java

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

发布时间:2025/3/16 java 73 豆豆
生活随笔 收集整理的这篇文章主要介绍了 Java描述设计模式(23):访问者模式 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

本文源码: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):访问者模式的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。