设计模式之Visitor(访问者)(转)
Visitor定义
作用于某个对象群中各个对象的操作. 它可以使你在不改变这些对象本身的情况下,定义作用于这些对象的新操作.
在Java中,Visitor模式实际上是分离了collection结构中的元素和对这些元素进行操作的行为.
为何使用Visitor?
Java的Collection(包括Vector和Hashtable)是我们最经常使用的技术,可是Collection好象是个黑色大染缸,本来有各种鲜明类型特征的对象一旦放入后,再取出时,这些类型就消失了.那么我们势必要用If来判断,如:
Iterator iterator = collection.iterator()
while (iterator.hasNext()) {
Object o = iterator.next();
if (o instanceof Collection)
messyPrintCollection((Collection)o);
else if (o instanceof String)
System.out.println("'"+o.toString()+"'");
else if (o instanceof Float)
System.out.println(o.toString()+"f");
else
System.out.println(o.toString());
}
在上例中,我们使用了 instanceof来判断 o的类型.
很显然,这样做的缺点代码If else if 很繁琐.我们就可以使用Visitor模式解决它.
如何使用Visitor?
针对上例,我们设计一个接口visitor访问者:
public interface Visitor
{
public void visitCollection(Collection collection);
public void visitString(String string);
public void visitFloat(Float float);
}
在这个接口中,将我们认为Collection有可能的类的类型放入其中.
有了访问者,我们需要被访问者,被访问者就是我们Collection的每个元素Element,我们要为这些Element定义一个可以接受访问的接口(访问和被访问是互动的,只有访问者,被访问者如果表示不欢迎,访问者就不能访问)
我们定义这个接口叫Visitable,用来定义一个Accept操作,也就是说让Collection每个元素具备可访问性.
public interface Visitable
{
public void accept(Visitor visitor);
}
好了,有了两个接口,我们就要定义他们的具体实现(Concrete class):
public class ConcreteElement implements Visitable
{
private String value;
public ConcreteElement(String string) {
value = string;
}
//定义accept的具体内容 这里是很简单的一句调用
public void accept(Visitor visitor) {
visitor.visitString(this);
}
}
再看看访问者的Concrete实现:
public class ConcreteVisitor implements Visitor
{
//在本方法中,我们实现了对Collection的元素的成功访问
public void visitCollection(Collection collection) {
Iterator iterator = collection.iterator()
while (iterator.hasNext()) {
Object o = iterator.next();
if (o instanceof Visitable)
((Visitable)o).accept(this);
}
public void visitString(String string) {
System.out.println("'"+string+"'");
}
public void visitFloat(Float float) {
System.out.println(float.toString()+"f");
}
}
在上面的visitCollection我们实现了对Collection每个元素访问,只使用了一个判断语句,只要判断其是否可以访问.
至此,我们完成了Visitor模式基本架构.
使用Visitor模式的前提
对象群结构中(Collection) 中的对象类型很少改变,也就是说访问者的身份类型很少改变,如上面中Visitor中的类型很少改变,如果需要增加新的操作,比如上例中我们在ConcreteElement具体实现外,还需要新的ConcreteElement2 ConcreteElement3.
可见使用Visitor模式是有前提的,在两个接口Visitor和Visitable中,确保Visitor很少变化,变化的是Visitable,这样使用Visitor最方便.
如果Visitor也经常变化, 也就是说,对象群中的对象类型经常改变,一般建议是,不如在这些对象类中逐个定义操作.但是Java的Reflect技术解决了这个问题.
Reflect技术是在运行期间动态获取对象类型和方法的一种技术,具体实现参考Javaworld的英文原文.
转自:http://www.jdon.com 板桥里人
设计模式之Visitor(访问者)(转)的更多相关文章
- 设计模式 ( 二十 ) 访问者模式Visitor(对象行为型)
设计模式 ( 二十 ) 访问者模式Visitor(对象行为型) 1.概述 在软件开发过程中,对于系统中的某些对象,它们存储在同一个集合collection中,且具有不同的类型,而且对于该集合中的对象, ...
- 设计模式23:Visitor 访问者模式(行为型模式)
Visitor 访问者模式(行为型模式) 动机(Motivation)在软件构造过程中,由于需求的改变,某些类层次结构中常常需要增加新的行为(方法),如果直接在基类中做这样的修改,将会给子类带来繁重的 ...
- 浅谈设计模式-visitor访问者模式
先看一个和visitor无关的案例.假设你现在有一个书架,这个书架有两种操作,1添加书籍2阅读每一本书籍的简介. //书架public class Bookcase { List<Book> ...
- 重学 Java 设计模式:实战访问者模式「模拟家长与校长,对学生和老师的不同视角信息的访问场景」
作者:小傅哥 博客:https://bugstack.cn - 原创系列专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 能力,是你前行的最大保障 年龄会不断的增长,但是什么才能让你不 ...
- 设计模式学习之访问者模式(Visitor,行为型模式)(21)
参考:https://www.cnblogs.com/edisonchou/p/7247990.html 在患者就医时,医生会根据病情开具处方单,很多医院都会存在以下这个流程:划价人员拿到处方单之后根 ...
- 《JAVA设计模式》之访问者模式(Visitor)
在阎宏博士的<JAVA与模式>一书中开头是这样描述访问者(Visitor)模式的: 访问者模式是对象的行为模式.访问者模式的目的是封装一些施加于某种数据结构元素之上的操作.一旦这些操作需要 ...
- 设计模式C++学习笔记之十八(Visitor访问者模式)
18.1.解释 概念:表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作. main(),客户 IVisitor,访问者接口 CBaseVis ...
- 十三、Visitor 访问者设计模式
需求:将数据结果与处理分开 设计原理: 代码清单: Element public interface Element { void accept(Visitor visitor); } Entry p ...
- 13、Visitor 访问者模式 访问数据结构并处理数据 行为型设计模式
1.模式的定义与特点 访问者(Visitor)模式的定义:将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元 ...
随机推荐
- UVA11491 奖品的价值
奖品的价值C804 运行时间限制:1000ms: 运行空间限制:51200KB 试题描述 你是一个电视节目的获奖嘉宾.主持人在黑板上写出一个 n 位非负整数(不以 0 开头),邀请你删除其中的 d 个 ...
- tomcat 的acceptCount、acceptorThreadCount、maxConnections、maxThreads 如何确定
acceptCount 连接在被ServerSocketChannel accept之前就暂存在这个队列中,acceptCount就是这个队列的最大长度. ServerSocketChannel ac ...
- jquery实现简单的弹出框
弹出框本身是一个div,默认是隐藏不展示的,在需要弹框的时候使其显示,并浮在当前页面之上 弹框样式: .tanchuang { width: 100%; height: 100%; display: ...
- Exception in thread “main” java.sql.SQLException: No suitable driver
问题背景:通过Spark SQL的jdbc去读取Oracle数据做测试,在本地的idea中没有报任务错误.但是打包到集群的时候报: Exception in thread “main” java.sq ...
- [js]Object.defineProperty等几个js特殊方法
Object.defineProperty var obj = { test: "hello" }; obj['favor'] = 'orange'; //对象已有的属性添加特性描 ...
- LuaFileSystem
bokeyuan_1234 lua的文件管理 lua没有自己的文件管理 只有读取和写入文件,但是可以通过调用lfs(LuaFileSystem),lfs是一个 用于lua进行文件访问的库,支持lua5 ...
- 【Java】-NO.16.EBook.4.Java.1.001-【疯狂Java讲义第3版 李刚】- UML
1.0.0 Summary Tittle:[Java]-NO.16.EBook.4.Java.1.001-[疯狂Java讲义第3版 李刚]- Style:EBook Series:Java Since ...
- 【Linux】-NO.8.Linux.4.Command.1.001-【Common Command】-
1.0.0 Summary Tittle:[Linux]-NO.8.Linux.4.Command.1.001-[Common Command]- Style:Linux Series:Command ...
- 【LeetCode每天一题】Longest Common Prefix(最长前缀)
Write a function to find the longest common prefix string amongst an array of strings. If there is n ...
- 【LeetCode每天一题】Pascal's Triangle(杨辉三角)
Given a non-negative integer numRows, generate the first numRows of Pascal's triangle. In Pascal's t ...