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 条评论
登录 后参与评论

相关文章

来自专栏码匠的流水账

聊聊storm tuple的序列化

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

694
来自专栏Hongten

python开发_calendar

如果你用过linux,你可能知道在linux下面的有一个强大的calendar功能,即日历

1022
来自专栏码匠的流水账

聊聊flink的SourceFunction

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

1403
来自专栏一个会写诗的程序员的博客

禅与 JavaScript 编程艺术, Zen and The Art of JavaScript Programming禅与 JavaScript 编程艺术

Zen and The Art of JavaScript Programming

941
来自专栏更流畅、简洁的软件开发方式

[自定义服务器控件] 第三步:CheckBoxList。

前面发了文本框和下拉列表框的,这回发一个CheckBoxList。不知道中文名字该叫什么。 CheckBoxList 最郁闷的地方就是:明明可以选择多个选项,但...

2106
来自专栏五分钟学算法

LeeCode题目图解

There is an English version of README here. just click it!

1422
来自专栏码匠的流水账

springboot2自定义statsd指标前缀

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

1072
来自专栏码匠的流水账

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

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

811
来自专栏desperate633

LeetCode Fizz Buzz题目分析代码

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

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

Code forces 719A Vitya in the Countryside

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

3356

扫码关注云+社区