JAVA 设计模式 访问者模式

用途

访问者模式 (Visitor)

表示一个作用于某对象结构中的各元素的操作。 它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

访问者模式是一种行为型模式

用途

图-访问者模式结构图

Visitor : 为该对象结构中 ConcreteElement 的每一个类声明一个 Visit 操作。

abstract class Visitor {
 public abstract void VisitConcreteElementA(ConcreteElementA elementA);
 public abstract void VisitConcreteElementB(ConcreteElementB elementB);
 }

ConcreteVisitor : 实现每个由 Visitor 声明的操作。每个操作实现算法的一部分,而该算法片段乃是对应于结构中对象的类。

class ConcreteVisitor1 extends Visitor {
     @Override
 public void VisitConcreteElementA(ConcreteElementA elementA) {
         System.out.println(this.getClass().getName() + " 访问 " + elementA.getClass().getName());
     }
 
     @Override
 public void VisitConcreteElementB(ConcreteElementB elementB) {
         System.out.println(this.getClass().getName() + " 访问 " + elementB.getClass().getName());
     }
 }
 
 class ConcreteVisitor2 extends Visitor {
     @Override
 public void VisitConcreteElementA(ConcreteElementA elementA) {
         System.out.println(this.getClass().getName() + " 访问 " + elementA.getClass().getName());
     }
 
     @Override
 public void VisitConcreteElementB(ConcreteElementB elementB) {
         System.out.println(this.getClass().getName() + " 访问 " + elementB.getClass().getName());
     }
 }

Element : 定义一个Accpet操作,它以一个访问者为参数。

abstract class Element {
 public abstract void Accept(Visitor visitor);
 }

ConcreteElement : 实现 Element 声明的 Accept 操作。

class ConcreteElementA extends Element {
     @Override
 public void Accept(Visitor visitor) {
         visitor.VisitConcreteElementA(this);
     }
 }
 
 class ConcreteElementB extends Element {
     @Override
 public void Accept(Visitor visitor) {
         visitor.VisitConcreteElementB(this);
     }
 }

ObjectStructure : 可以枚举它的元素,可以提供一个高层的接口以允许访问者访问它的元素。

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 elem : elements) {
             elem.Accept(visitor);
         }
     }
 }

测试代码

public class VisitorPattern {
 public static void main(String[] args) {
         ObjectStructure o = new ObjectStructure();
         o.Attach(new ConcreteElementA());
         o.Attach(new ConcreteElementB());
 
         ConcreteVisitor1 v1 = new ConcreteVisitor1();
         ConcreteVisitor2 v2 = new ConcreteVisitor2();
 
         o.Accept(v1);
         o.Accept(v2);
     }
 }

运行结果

 ConcreteVisitor1 访问 ConcreteElementA
 ConcreteVisitor1 访问 ConcreteElementB
 ConcreteVisitor2 访问 ConcreteElementA
 ConcreteVisitor2 访问 ConcreteElementB

推荐

本文属于 JAVA设计模式系列

参考资料

《大话设计模式》《HeadFirst设计模式》

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏函数式编程语言及工具

SDP(9):MongoDB-Scala - data access and modeling

    MongoDB是一种文件型数据库,对数据格式没有硬性要求,所以可以实现灵活多变的数据存储和读取。MongoDB又是一种分布式数据库,与传统关系数据库不同...

41040
来自专栏码匠的流水账

聊聊storm tuple的序列化

storm-2.0.0/storm-client/src/jvm/org/apache/storm/executor/ExecutorTransfer.java

10040
来自专栏云霄雨霁

加权有向图----加权有向图的实现

26900
来自专栏码匠的流水账

springboot2自定义statsd指标前缀

springboot2引入了micrometer,1.x版本的spring.metrics.export.statsd.prefix在2版本中已经被标记为废弃,...

17220
来自专栏码匠的流水账

聊聊flink的SourceFunction

flink-streaming-java_2.11-1.6.2-sources.jar!/org/apache/flink/streaming/api/func...

33430
来自专栏码匠的流水账

聊聊eureka client的fetch-remote-regions-registry属性

本文主要研究一下eureka client的fetch-remote-regions-registry属性

20310
来自专栏Jerry的SAP技术分享

使用com.sun.imageio.plugins.png.PNGMetadata读取图片的元数据

所谓图片元数据,就是除了我们肉眼看到的图片内容外,隐藏在这些内容背后的一些技术数据。

19840
来自专栏软件开发 -- 分享 互助 成长

CRC校验码

循环冗余校验码(CRC)的基本原理是:在K位信息码后再拼接R位的校验码,整个编码长度为N位,因此,这种编码也叫(N,K)码。对于一个给定的(N,K)码,可以证明...

34760
来自专栏小樱的经验随笔

Code forces 719A Vitya in the Countryside

A. Vitya in the Countryside time limit per test:1 second memory limit per test:2...

37460
来自专栏desperate633

LeetCode Fizz Buzz题目分析代码

Write a program that outputs the string representation of numbers from 1 to n.

9510

扫码关注云+社区

领取腾讯云代金券