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

相关文章

来自专栏LinkedBear的个人空间

设计模式笔记(七)——状态模式 原

类的行为是基于它的状态改变的。状态模式使得允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类。

471
来自专栏互扯程序

Java8函数式编程实践精华

现在是资源共享的时代,同样也是知识分享的时代,如果你觉得本文能学到知识,请把知识与别人分享。

913
来自专栏程序员宝库

移除注释的完善思路:真的可以用正则实现?

网上有很多自称能实现移除JS注释的正则表达式,实际上存在种种缺陷。这使人多少有些愕然,也不禁疑惑到:真的可以用正则实现吗?而本篇文章以使用正则移除JS注释为目标...

1003
来自专栏郭霖

Ruby设计模式透析之 —— 模板方法(Template Method)

Java设计模式透析之 —— 模版方法(Template Method) 今天你还是像往常一样来上班,一如既往地开始了你的编程工作。 项目经理告诉你,今天想在...

2057
来自专栏java学习

Java每日一练(2017/8/12)

最新通知 ●回复"每日一练"获取以前的题目! ●【新】Android视频更新了!(回复【安卓视频】获取下载链接) ●【新】Ajax知识点视频更新了!(回复【学习...

2464
来自专栏desperate633

一个故事带你搞懂ASCII,Unicode字符集和UTF-8编码

快下班时,爱问问题的小朋友Nico又问了一个问题: "sqlserver里面有char和nchar,那个n据说是指unicode的数据,这个是什么意思。" ...

742
来自专栏Jackson0714

算法也是很过瘾的~~用面向对象实现~夜过吊桥~算法

28711
来自专栏司想君

前端也要学系列:设计模式之装饰者模式

今天我们来讲另外一个非常实用的设计模式:装饰者模式。这个名字听上去有些莫名其妙,不着急,我们先来记住它的一个别名:包装器模式。

762
来自专栏web前端教室

聊一下JavaScript定时器

image.png 话说JS的定时器,常用的其实就是setTimeout和setInterval这二个。它们俩一个是运行一次就拉倒,另一个是你不叫我停我就一...

1839
来自专栏web前端教室

1103《浅淡vueJs的生命周期?》| 本次微课总结

今天,11月3日晚22点的微课,已经结束了,内容主要是讲了vueJs的生命周期。 我在微课中并不是按vue实例,从产生到工作到消失的过程来讲解。而是将它分成了四...

1926

扫码关注云+社区