访问者模式是对象的行为模式。访问者模式的目的是封装施加在某种数据结构元素上的操作。一旦一些操作需要修改,接受这个操作的数据结构可以保持不变。

个人觉得访问者模式相对其他的设计模式来说稍微复杂,难理解一点,要理解这个模式首先需要了解“单分派与多分派”。

单分派与多分派

根据对象的类型对执行方法进行选择,就是分派(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)模式的更多相关文章

  1. 设计模式之visitor模式,人人能懂的有趣实例

    设计模式,现在在网上随便搜都一大堆,为什么我还要写"设计模式"的章节呢? 两个原因: 1.本人觉得这是一个有趣的设计模式使用实例,所以记下来: 2.看着设计模式很牛逼,却不知道怎么 ...

  2. 设计模式之——visitor模式

    visitor模式,又叫访问者模式,把结构和数据分开,编写一个访问者,去访问数据结构中的元素,然后把对各元素的处理全部交给访问者类.这样,当需要增加新的处理时候,只需要编写新的 访问者类,让数据结构可 ...

  3. 设计模式C++描述----22.访问者(Visitor)模式

    一. 访问者模式 定义:表示一个作用于某对象结构中的各元素的操作.它你可以在不改变各元素的类的前提下定义作用于这些元素的新操作. 结构如下: 二. 举例 假设有一项科学实验,是用来对比两种种子在不同环 ...

  4. [设计模式]访问者 Visitor 模式

    访问者模式是对象的行为模式. 访问者模式的目的是封装一些施加于某种数据结构元素之上的操作.一旦这些操作需要修改的话,接受这个操作的数据结构则可以保持不变.

  5. 设计模式之Visitor模式(笔记)

    訪问者模式:表示一个作用于某个对象结构中的各元素操作.它使你能够不改变各元素的类的前提下定义作用于这些元素的新操作. 首先定义一个visitor抽象类,为每一个详细类声明一个visit操作 publi ...

  6. 设计模式:visitor模式

    核心:将数据结构和数据的处理分开 注意:注意函数的参数传递和调用关系 例子: class Element; class Visitor { public: virtual void Visit(Ele ...

  7. 设计模式 -- 访问者模式(Visitor)

    写在前面的话:读书破万卷,编码如有神--------------------------------------------------------------------主要内容包括: 初识访问者模 ...

  8. Visitor模式(访问者设计模式)

    Visitor ? 在Visitor模式中,数据结构与处理被分离开来.我们编写一个表示"访问者"的类来访问数据结构中的元素, 并把对各元素的处理交给访问者类.这样,当需要增加新的处 ...

  9. .NET设计模式访问者模式

    一.访问者模式的定义: 表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作. 二.访问者模式的结构和角色: 1.Visitor 抽象访问者角色,为该 ...

随机推荐

  1. L159

    Waves are the children of the struggle between ocean and atmosphere, the ongoing signatures of infin ...

  2. Composer 扩展包安装方法

    问题说明 我们经常要往现有的项目中添加扩展包,有时候因为文档的错误引导,如下图来自 这个文档 的: composer update 这个命令在我们现在的逻辑中,可能会对项目造成巨大伤害. 因为 com ...

  3. 4. 什么是应用服务器? - JavaEE基础系列

    本文是JavaEE基础系列的第四节. Java EE简介 - JavaEE基础系列 JSR简介 - JavaEE基础系列 什么是JSR参考实现? - JavaEE基础系列 上一节介绍了什么是JSR参考 ...

  4. Python如何输出带颜色的文字

    print('\033[31m%s' % "这是前景色") 这是前景色 print('%s' % "这是前景色") 这是前景色 print('\033[1;31 ...

  5. [Linux] jq:命令行JSON处理工具

    jq命令帮助我们很方便地在终端查看和处理json文件 jq命令的帮助信息: abby@abby:bgs$ jq -h jq - commandline JSON processor [version ...

  6. Python中的collections模块

    Python中内置了4种数据类型,包括:list,tuple,set,dict,这些数据类型都有其各自的特点,但是这些特点(比如dict无序)在一定程度上对数据类型的使用产生了约束,在某些使用场景下效 ...

  7. json中的dumps和loads

    常用有2个方法,也是最基本的使用方法: 1.dumps:把字典转成json字符串 进行post的请求的时候就要用json.dumps来进行装换,利用get方法就可以不用了. 2.loads:把json ...

  8. php自动添加相关文章

    {pc:content action="relation" relation="$relation" id="$id" catid=&quo ...

  9. windows命令行工具

    winver 检查Windows版本 wmimgmt.msc 打开Windows管理体系结构(wmi) wupdmgr Windows更新程序 wscript Windows脚本宿主设置 write ...

  10. php开发中一些前端知识杂总

    推荐几个jqyuey插件的好地方 http://jqueryui.com/ http://www.jq22.com/ 背景: 服务端采用ci3.0框架,twig作为模板嵌套. twig模板手册: ht ...