jeffyan77能不能举个例子讲一下 visitor 模式?谢谢

eagle19790214 2003-09-12 02:20:22
加精
我觉得visitor模式和iterator模式都是在要访问的对象上放了一个钩子,让外部对象能访问自己,最好再说说区别,谢谢!
...全文
102 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
swinging 2003-09-15
  • 打赏
  • 举报
回复
还有,纠正下自己的错误,
设计模式最核心的,恐怕还是解决问题的设计思想,
而使用设计模式和分辨模式我认为问题域还是很重要。
继续努力学。
sweat
swinging 2003-09-15
  • 打赏
  • 举报
回复
其实今天早上仔细想了,
觉得这2个模式解决问题的核心设计思想也不是那么相同,
虽然我描述不清楚两个的设计思想,
但是感觉是不同的。
如果有人详细说说就好了。
jeffyan77 2003-09-14
  • 打赏
  • 举报
回复
To swinging(山不在高) : 呵呵,你多数观点我其实是同意的,但是体认Visitor模式的重要一点就是它实际上是对Iterator模式的推广。国内读者大多没有看到这一点,这不是他们的问题,这个问题可能来自于《设计模式》一书的中文翻译。

《设计模式》一书的翻译水平是相当不错的,但是智者千虑必有一失,在Visitor一章有一个微妙的错误。这个错误影响了很多中文版的读者,几乎所有和我讨论过Visitor模式的朋友都好像受到了影响,所以我特地在这里指出这个失误。

英文版336页原文如下:
4. Visiting across class hierarchies. An iterator (see Iterator (257)) can visit the objects in a structure as it traverses them by calling their operations. But an interator can't work across object structures with different types of elements.

对应中文版221页
4)通过类层次进行访问 一个迭代器(参见Iterator(5.4))可以通过调用节点对象的特定操作来遍历整个对象结构,同时访问这些对象。但是迭代器不能对具有不同元素类型的对象结构进行操作。

错误之处在于不懂across这个介词,并且没有注意到hierarchies和object structures是复数。我的翻译如下:

across:跨越,横跨
across hierarchies: 跨越多个层次
across object structures :横跨多个对象结构

4)进行跨越多个类层次的访问。通过调用一个结构中的对象的某些操作,一个迭代器可以遍历这些对象。但是一个迭代器无法跨越具有不同类型的元素的几个对象结构进行工作。

错的很微妙,但使得中文读者无法读懂这段话了。理解这段话,对理解Iterator与Visitor模式的关系很重要。

这本书的译者应该说专业水平和英文水平都相当不错,但是英文的介词是著名的困难,而中国人的通病是对复数不敏感。我早些时候粗粗地读了中译本,发现了几个地方犯了类似的毛病,现在一下子找不到了,以后看到再说吧。
eagle19790214 2003-09-14
  • 打赏
  • 举报
回复
多谢两位指教,我又看了一下英文版的,明白了,哈哈,多谢,结帐
swinging 2003-09-14
  • 打赏
  • 举报
回复
必须承认,我对模式这本书阅读的仔细程度是很低的,^_^
至今是有空翻翻中文版的,不过中文版的最大问题就是翻译太英文化(个人感觉),
有时候我是读一个句子要很久才明白它的意思(太长而且太多修饰词的句子实在让人痛苦),甚至有些实在没法子明白只好跳过,
当然,自己英文更差些,所以硬着头皮先读中文的。

虽然这样,对于以下这句:
但是体认Visitor模式的重要一点就是它实际上是对Iterator模式的推广

我不是很赞同,
仔细想想,好像你这里用推广好像是可以勉强过得去,但是单说VISITOR是ITERATOR的推广
好像掩盖了它们之间的本质不同

ITERATOR强调对一个聚合对象的访问,
VISITOR强调对对象结构元素的操作,

按照我的理解,简单的比喻,如果说ITERATOR是坐标的X轴,那么VISITOR是坐标的Y轴,

它们解决问题的基本思想是很相似的(这里可以赞同你的“推广”一词,可是到底是谁推广谁呢?^_^),不过问题域是截然不同的,这也是我说两个模式根本可以同时使用来更好的解决问题,就好像,
单有一个X轴只能表示一维,而且能很好得处理很多问题,如果加上Y轴,支撑起来一个面,解决问题的空间更广阔了。(这个比喻不是特别恰当不必细扣,不是说一定两者合一才更好,而是拿它们的方向比喻问题域,同样是坐标上的1,它在X轴和Y轴的位置相对于整个坐标轴是不同的)

最后,我的观点,模式用来解决问题,所以模式所对应的问题域是决定性的,
虽然VISITOR和ITERATOR我也赞同它们解决问题的思想基本相同,但是问题域却截然不同,
所以它们是有本质区别的。


请原谅我的咬文嚼字(其实我认为是你逼我的,^_^,!-_-),
很高兴和你讨论这个问题,这让我更细致地考虑它们。
swinging 2003-09-13
  • 打赏
  • 举报
回复
iterator:提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。

visitor:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

不明白楼主为什么对这两个会需要显示去区别,我想这两个模式不是属于同一个问题域的,楼上的比喻也很好得说明了这一点,大多数时候不需要考虑在这2者之间选择一个使用,你看,其实按楼上得比喻,这2者根本是要一起使用才能达到好得效果的。

实际上很多模式本身是有很多相似点的,不能单看对象之间是如何访问的,
照你那么说,大多数模式不就是几个对象之间通过接口相互访问吗?
模式很重要的东西还有本身的适用性,我想你多了解它的适用性会更好地去区分它们。
还有,我的体会是,模式是解决问题的,不是区分技术的。
jeffyan77 2003-09-12
  • 打赏
  • 举报
回复
你认为visitor和iterator模式有共同点,这说明你对两个模式还是有一定认识的。

如果有一棵继承树,你要使用某个独立的对象遍历这棵树,并且呼叫树上某一个共同的方法,那么你使用iterator。比如这是一棵苹果树,你使用一个摘苹果的杆子把苹果一个一个摘下来,这就是iterator。

现在你有好几棵树,苹果树、葡萄树、酸枣树等,对每一种果实,你都有不同的杆子,摘取果实。这个时候就可以使用visitor模式

当然,Java对象都源自Ojbect类,所以原则上所有的对象都来自同一棵树,以Object为根。这时候不妨假设一棵树有不同的子树,或者同一棵树上有不同的果实。

不使用visitor模式行不行,行。那你就使用Iterator模式,像这样:

while(it.hasNext()){
Object o = it.next();
if (苹果 instanceof o){...}
else if(葡萄 instanceof o){...}
。。。
}

这样好像也没什么问题,只是一旦有操作进来,比如要给不同的树打不同的农药,就要改写这个条件转移。

用了Visitor模式之后呢,奇迹发生了,你拿出所有的杆子举到每一个果实那里,苹果会自己找到摘苹果的杆子,让杆子把自己摘下来,葡萄会找到摘葡萄的杆子,把自己摘下来。

如果有打农药、授粉等等任务进来,Visitor模式可以允许动态加入一个新的visitor类代表打农药、授粉等,做到这一点不需要修改代码。这就是OCP。你把所有的农药都放到每一个果实跟前,果实就自行找到正确的农药自己打上。把所有的花粉放到果实跟前,果实就自己找到正确的花粉授粉。

你只有这些种水果杆子/农药/花粉,如果你有新的水果种类,对不起,只好改写代码。Visitor模式不支持这种情况下的OCP。

怎么样,是不是明白了一点?呵呵
C#设计模式(1) 一、 C# 面向对象程序设计复习 二、 设计模式举例 三、 先有鸡还是先有蛋? 四、 大瓶子套小瓶子还是小瓶子套大瓶子? 五、 .net本质 C#设计模式(2) 一、 "开放-封闭"原则(OCP) 二、 里氏代换原则(LSP) C#设计模式(3) 三、 依赖倒置原则(DIP) 四、 接口隔离原则(ISP) 五、 合成/聚合复用原则(CARP) 六、 迪米特法则(LoD) C#设计模式(4)-Simple Factory Pattern 一、 简单工厂(Simple Factory)模式 二、 Simple Factory模式角色与结构: 三、 程序举例: 四、 Simple Factory模式演化 五、 优点与缺点: C#设计模式(5)-Factory Method Pattern 一、 工厂方法(Factory Method)模式 二、 Factory Method模式角色与结构: 三、 程序举例: 四、 工厂方法模式与简单工厂模式 五、 Factory Method模式演化 六、 Factory Method模式与其它模式的关系 七、 另外一个例子 C#设计模式(6)-Abstract Factory Pattern 一、 抽象工厂(Abstract Factory)模式 二、 Abstract Factory模式的结构: 三、 程序举例: 四、 在什么情形下使用抽象工厂模式: 五、 抽象工厂的起源 六、 Abstract Factory模式在实际系统中的实现 七、 "开放-封闭"原则 C#设计模式(7)-Singleton Pattern 一、 单例(Singleton)模式 二、 Singleton模式的结构: 三、 程序举例: 四、 在什么情形下使用单例模式: 五、 Singleton模式在实际系统中的实现 六、 C#中的Singleton模式 C#设计模式(8)-Builder Pattern 一、 建造者(Builder)模式 二、 Builder模式的结构: 三、 程序举例: 四、 建造者模式的活动序列: 五、 建造者模式的实现: 六、 建造者模式的演化 七、 在什么情况下使用建造者模式 C#设计模式(9)-Prototype Pattern 一、 原型(Prototype)模式 二、 Prototype模式的结构: 三、 程序举例: 四、 带Prototype Manager的原型模式 五、 浅拷贝与深拷贝 六、 Prototype模式的优点与缺点 C#设计模式(10)-Adapter Pattern 一、 适配器(Adapter)模式 二、 类的Adapter模式的结构: 三、 类的Adapter模式示意性实现: 四、 对象的Adapter模式的结构: 五、 对象的Adapter模式示意性实现: 六、 在什么情况下使用适配器模式 七、 一个实际应用Adapter模式例子 八、 关于Adapter模式的讨论 C#设计模式(11)-Composite Pattern 一、 合成(Composite)模式 二、 合成模式概述 三、 安全式的合成模式的结构 四、 安全式的合成模式实现 五、 透明式的合成模式结构 六、 透明式的合成模式实现 七、 使用合成模式时考虑的几个问题 八、 和尚的故事 九、 一个实际应用Composite模式例子 C#设计模式(12)-Decorator Pattern 一、 装饰(Decorator模式 二、 装饰模式的结构 三、 装饰模式示例性代码 四、 装饰模式应当在什么情况下使用 五、 装饰模式实际应用的例子 六、 使用装饰模式的优点和缺点 七、 模式实现的讨论 八、 透明性的要求 九、 装饰模式在.NET中的应用 C#设计模式(13)-Proxy Pattern 一、 代理(Proxy)模式 二、 代理的种类 三、 远程代理的例子 四、 代理模式的结构 五、 代理模式示例性代码 六、 高老庄悟空降八戒 七、 不同类型的代理模式 八、 代理模式实际应用的例子 设计模式(14)-Flyweight Pattern 一、 享元(Flyweight)模式 二、 单纯享元模式的结构 三、 单纯享元模式的示意性源代码 四、 复合享元模式的结构 五、 一个咖啡摊的例子 六、 咖啡屋的例子 七、 享元模式应当在什么情况下使用 八、 享元模式的优点和缺点 设计模式(15)-Facade Pattern 一、 门面(Facade)模式 二、 门面模式的结构 三、 门面模式的实现 四、 在什么情况下使用门面模式 五、 一个例子 六、 使用门面模式的设计 设计模式(16)-Bridge Pattern 一、 桥梁(Bridge)模式 二、 桥梁模式的结构 三、 桥梁模式的示意性源代码 四、 调制解调器问题 五、 另外一个实际应用Bridge模式例子 六、 在什么情况下应当使用桥梁模式 设计模式(17)-Chain of Responsibility Pattern 一、 职责链(Chain of Responsibility)模式 二、 责任链模式的结构 三、 责任链模式的示意性源代码 四、 纯的与不纯的责任链模式 五、 责任链模式的实际应用案例 六、 责任链模式的实现 设计模式(18)-Command Pattern 一、 命令(Command)模式 二、 命令模式的结构 三、 命令模式的示意性源代码 四、 玉帝传美猴王上天 五、 命令模式的实现 六、 命令模式的实际应用案例 七、 在什么情况下应当使用命令模式 八、 使用命令模式的优点和缺点 设计模式(19)-Observer Pattern 一、 观察者(Observer)模式 二、 观察者模式的结构 三、 观察者模式的示意性源代码 四、 C#中的Delegate与Event 五、 一个实际应用观察者模式例子 六、 观察者模式的优缺点 设计模式(20)-Visitor Pattern 一、 访问者(Visitor模式 二、 访问者模式的结构 三、 示意性源代码 四、 一个实际应用Visitor模式例子 五、 在什么情况下应当使用访问者模式 六、 使用访问者模式的优点和缺点 设计模式(21)-Template Method Pattern 一、 模板方法(Template Method)模式 二、 模版方法模式的结构 三、 模板方法模式的示意性代码 四、 继承作为复用的工具 五、 一个实际应用模板方法的例子 六、 模版方法模式中的方法 七、 重构的原则 设计模式(22)-Strategy Pattern 一、 策略(Strategy)模式 二、 策略模式的结构 三、 示意性源代码 四、 何时使用何种具体策略角色 五、 一个实际应用策略模式例子 六、 在什么情况下应当使用策略模式 七、 策略模式的优点和缺点 八、 其它

50,528

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧