设计模式-访问者(Visitor)模式
访问者模式是对象的行为模式。访问者模式的目的是封装施加在某种数据结构元素上的操作。一旦一些操作需要修改,接受这个操作的数据结构可以保持不变。
个人觉得访问者模式相对其他的设计模式来说稍微复杂,难理解一点,要理解这个模式首先需要了解“单分派与多分派”。
单分派与多分派
根据对象的类型对执行方法进行选择,就是分派(Dispatch)。分派是面向对象语言提供的关键特性之一,根据分派发生的时期,可分为两种,静态分派和动态分派。静态分派发生在编译时期,动态分派发生在执行时期。
重载方法的分派是根据静态类型进行的,分派过程发生在编译时期,属于静态分派。
Java通过Override重写来支持动态分派,Java编译器并不会知道执行阶段会执行哪段重写的方法。
Java语言支持静态的多分派和动态的单分派,分别是通过重载方法和重写方式实现的。
Java语言通过两个宗量来决定执行哪一段代码:
方法的接受者:也即方法执行的对象,方法的接受者,动态分派根据具体类型决定;
事件对象:一个类行为的对象,传输的参数类型。
而访问者模式就是通过重写和重载的结合使用来达到实现双重分派的目的。
访问者模式
下面结合我们实际项目中的需求来阐述一下访问者模式。
访问者模式的类图如下:

所涉及到的角色:
抽象访问者:声明一个或多个访问操作,形成所有的具体元素角色必须实现的接口。下面的示例就是资源访问操作的顶层接口。
public interface IResourceVisitor {
//detail resource
void visit(JavaClassResource resource) throws ResourceParserException;
void visit(MetadataResource resource) throws ResourceParserException;
void visit(UpmResource resource) throws ResourceParserException;
void visit(XmlResource resource) throws ResourceParserException;
void visit(PropertiesResource propertiesResource) throws ResourceParserException;
//composite resource
void visit(BusinessComponentResource resource) throws ResourceParserException;
void visit(JavaClassSrcResource resource) throws ResourceParserException;
具体访问者:实现抽象访问者角色所声明的接口,就是抽象访问所声明的各个访问操作。一般情况下,由于一般情况下抽象访问者的方法都比较多,而且具体访问者也不会关心抽象访问者的所有方法,因此通常有一个默认的实现Adaptor介于两者之间。
Adaptor也是一个非常重要的类,对于Composite类型的资源,存在一个默认遍历策略。
public abstract class AbstractResourceVisitorAdaptor implements IResourceVisitor {
@Override
public void visit(JavaClassResource resource) throws ResourceParserException {
}
@Override
public void visit(MetadataResource resource) throws ResourceParserException {
}
@Override
public void visit(UpmResource resource) throws ResourceParserException {
}
@Override
public void visit(XmlResource resource) throws ResourceParserException {
}
@Override
public void visit(PropertiesResource propertiesResource) throws ResourceParserException {
}
@Override
public final void visit(BusinessComponentResource resource) throws ResourceParserException {
visitComposite(resource);
}
protected final void visitComposite(CompositeResource compositeResource) throws ResourceParserException {
List<IResource> subResources = compositeResource.getSubResources();
for (IResource subResource : subResources) {
subResource.accept(this);
}
}
}
抽象节点:声明一个接受操作,接受一个访问者对象作为一个参量。
public interface IResource {
/**
* Visitor mode to access resources.
*
* @param resourceVisitor
*/
void accept(IResourceVisitor resourceVisitor) throws ResourceParserException;
}
具体节点:实现抽象元素规定的accept操作,通常这个接口的层次结构反映了整个程序的数据结构。

结构对象: 结构对象可以遍历结构中的所有元素,如果需要,提供一个高层次的接口让访问者对象能够访问每一个元素;如果需要,可以设计成复合对象或一个聚集。
最终的UML类图结构如下所示(已隐藏过多的实现):

使用场景
访问者模式提供了一种倾斜的可扩展性,仅在当被访问的类结构非常稳定的时候使用(就比如PMD的类库中对Java代码结构进行了分析,Java类的结构语法相对来说非常稳定,其使用的就是访问者模式)。系统应该很少出现需要加入新节点的情况。其倾斜的可扩展性体现在:方法集合的可扩展性和类集合的不可扩展性。
设计模式-访问者(Visitor)模式的更多相关文章
- 设计模式之visitor模式,人人能懂的有趣实例
设计模式,现在在网上随便搜都一大堆,为什么我还要写"设计模式"的章节呢? 两个原因: 1.本人觉得这是一个有趣的设计模式使用实例,所以记下来: 2.看着设计模式很牛逼,却不知道怎么 ...
- 设计模式之——visitor模式
visitor模式,又叫访问者模式,把结构和数据分开,编写一个访问者,去访问数据结构中的元素,然后把对各元素的处理全部交给访问者类.这样,当需要增加新的处理时候,只需要编写新的 访问者类,让数据结构可 ...
- 设计模式C++描述----22.访问者(Visitor)模式
一. 访问者模式 定义:表示一个作用于某对象结构中的各元素的操作.它你可以在不改变各元素的类的前提下定义作用于这些元素的新操作. 结构如下: 二. 举例 假设有一项科学实验,是用来对比两种种子在不同环 ...
- [设计模式]访问者 Visitor 模式
访问者模式是对象的行为模式. 访问者模式的目的是封装一些施加于某种数据结构元素之上的操作.一旦这些操作需要修改的话,接受这个操作的数据结构则可以保持不变.
- 设计模式之Visitor模式(笔记)
訪问者模式:表示一个作用于某个对象结构中的各元素操作.它使你能够不改变各元素的类的前提下定义作用于这些元素的新操作. 首先定义一个visitor抽象类,为每一个详细类声明一个visit操作 publi ...
- 设计模式:visitor模式
核心:将数据结构和数据的处理分开 注意:注意函数的参数传递和调用关系 例子: class Element; class Visitor { public: virtual void Visit(Ele ...
- 设计模式 -- 访问者模式(Visitor)
写在前面的话:读书破万卷,编码如有神--------------------------------------------------------------------主要内容包括: 初识访问者模 ...
- Visitor模式(访问者设计模式)
Visitor ? 在Visitor模式中,数据结构与处理被分离开来.我们编写一个表示"访问者"的类来访问数据结构中的元素, 并把对各元素的处理交给访问者类.这样,当需要增加新的处 ...
- .NET设计模式访问者模式
一.访问者模式的定义: 表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作. 二.访问者模式的结构和角色: 1.Visitor 抽象访问者角色,为该 ...
随机推荐
- Ti IPNC Web网页之ActiveX控件
Ti IPNC Web网页之ActiveX控件 本篇介绍关于TI IPNC网页中播放器相关的东西. gStudio工程中添加播放器并控制播放器 打开IPNC网页时首先会自动下载ActiveX控件并安装 ...
- 正则表达式 preg_match 匹配中文
preg_match 匹配中文出错 2010年01月06日 星期三 14:55 错误提示: Warning: preg_match() [function.preg-match]: Compilati ...
- 完成users中的models
用户表中添加邮箱验证码数据表,轮播图数据表 from django.db import models from django.contrib.auth.models import AbstractUs ...
- 《gradle 用户指南中文版》 第一部分、关于Gradle
第一部分.关于Gradle 目录1.介绍1.1 关于本用户指南2.概述2.1 特性2.2 为什么选择Groovy? 上一页 | 目录 | 下一页
- 从JDK源码角度看Boolean
Java的Boolean类主要作用就是对基本类型boolean进行封装,提供了一些处理boolean类型的方法,比如String类型和boolean类型的转换. 主要实现源码如下: public fi ...
- 基于sklearn进行文本向量化
sklearn中,计数向量化用CountVectorizer,tfidf向量化用TfidfVectorizer: import pickle from sklearn.feature_extracti ...
- mailto web弹出outlook发送邮件
1. <pre name="code" class="html"><a href="Mailto:test@163.com?CC=t ...
- onerror="javascript:this.src='images/defaultUpload.png';"【容易导致死循环报错】
当无法找到默认图片时,onerror="javascript:this.src='images/defaultUpload.png';"容易导致死循环报错
- HTTP请求报头及其处理
ps:详细说明http://www.cnblogs.com/kkgreen/archive/2011/04/11/2012829.html
- 在liunx系统安装负载生成器(Load Generator)
#初始化系统 yum -y update yum -y install ntpdate ntpdate asia.pool.ntp.org yum -y install wget make cmake ...