关于visitor模式

ycl030379 2004-08-26 05:14:42
我看了visitor模式,越看越觉得不解,在被访问的类中要有一个accept(Visitor visitor)的方法,
这个方法的内容是:
visitor.visit(this);

在调用的时候是:
Visitor visitor = new Visitor();

beVisited.accept(visitor); // 问题在这里,为什么不直接改为visitor.visit(beVisited)呢,
//结果是一样的,绕了一圈,还是一样的效果

请各位大虾指教一下。
...全文
409 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
super_zzw 2005-08-27
  • 打赏
  • 举报
回复
首先要清楚Vistor模式解决的实际问题,其次要注意从系统分析角度出发考虑问题:
Visitor最主要的作用是使数据结构和算法相对独立,增加他们的扩展能力。
数据的抽象得到了接口方法Accept,accept不紧紧是接受vistor,最重要的是要选择相应的vistor.
而且从整个系统的角度出发来看, 系统依赖的应该是你的be visit的接口。 也就是说系统持有N多的数据,他们的数据结构可能各不相同, 那么系统如何调用对应的方法来处理对应的数据呢? 直接持有visitor的实例? 用visitor去调用be visitor好呢还是紧紧依赖be visitor的accept方法更好呢?
显然后者更好,因为你的系统只是依赖于be visitor的接口, 具体的方法由be visitor自己去决定。
所以,楼主的visitor.visit(beVisited)使你的系统依赖visitor的同时还要依赖be visitor,如果你要扩展数据接口和算法,都将影响你的系统。而使用accept使你的系统只依赖于be visitor接口。你可以增加be visitor类型(同时也增加相应的visitor方法),但是不会影响你的系统。
rongjf 2005-08-27
  • 打赏
  • 举报
回复
我个人觉得是模式需要解决的哪一类问题的问题。(1:n关系)
beVisited.accept(visitor);
说明已经有提供了很多不同方式的实现visitor(比如visitor1,visitor2),并且这些visitor都是针对beVisited的,你可以动态决定使用哪一个visitor来访问你的beVisited;
这里1是beVisited,n是visitor。

visitor.visit(beVisited)
说明你需要在visitor里面考虑beVisited接口有不同的实现情况(比如beVisited1,beVisited2),并有可能有不同的实现代码。
这里1是visitor,n是beVisited。

befree 2005-08-26
  • 打赏
  • 举报
回复
MK
peakpanda 2005-08-26
  • 打赏
  • 举报
回复
一个螺钉是可以和不同的螺母配合的,而不是只和一个。

大家只是在讨论问题,我也只是在实际编程的角度说问题,不是这位是否真的在实际应用中用到了这种一定要绑在一起的螺钉和螺母。
------------------------------------------------------
搂诸怎么还不结帖,思路也是真猪头,脑子真是锈住了。这不是绑定,是为了将一个部件分成两个部件以降低和其他接口的耦合性。如果应用场合变了,只更换其中一个就可以了,而不需要两个都换!
bluesu27 2004-09-06
  • 打赏
  • 举报
回复
我觉的首先那个被动和主动的解释很好,也许这就是visitor模式的主要目的吧。把选择权放在beVisitor中,就是起到回调的作用。对于beVisitor来说,关不关注visitor的操作无关紧要,反正visitor如果自己调用的话也能做,但是对于程序员和应用程序来说就不是那么安全了,确实无法想象当有很多beVisitors要进行很多次accepts操作时,我们要手工实例化visitors,然后还要去调用它们的visit方法,不但烦人还缺乏层次感。仔细观察j2se中的泪调用很多都用到了这种模式把
ycl030379 2004-09-04
  • 打赏
  • 举报
回复
增加你个*耦合,
------------------------------------
首先,请这位搞清楚,这里是大家讨论的地方,不是漫骂的地方。

螺钉和螺母
---------------------------------------
一个螺钉是可以和不同的螺母配合的,而不是只和一个。

大家只是在讨论问题,我也只是在实际编程的角度说问题,不是这位是否真的在实际应用中用到了这种一定要绑在一起的螺钉和螺母。
mycsdnid 2004-09-04
  • 打赏
  • 举报
回复
大家交流不要谩骂,我继续学习...
peakpanda 2004-09-03
  • 打赏
  • 举报
回复
其实如果我没有理解错的话,反而增加了它们之间的耦合,因为使用visitor模式,两个类就是相互依赖的关系了。
--------------------------------------------------------------------------------
增加你个*耦合,螺钉和螺母,是分开来和其他螺钉螺母搭配容易找到应用场合还是,合起来不分开的应用几率大?
indistinct_sword 2004-09-01
  • 打赏
  • 举报
回复
up先
liushmh 2004-08-27
  • 打赏
  • 举报
回复
其实我上面说的是个表现形式上的区别
主要原因其实是对象之间的关系以及程序设计上的语义决定了采用哪种方式。
beVisited.accept(visitor);
visitor.visit(beVisited);
两者间,前者visitor为被动式
而后者visitor是主动式
考虑当client需要对某个对象进行visit操作的时候,具体使用哪个visitor操作是用户自己选择的,所以visitor应该是作为宾语的形式出现。也就是用户需要visitor来进行visit操作,而不是说,visitor自己要主动进行visit操作。

这个其实和回调函数的操作是相同的。

zuxingyuan 2004-08-27
  • 打赏
  • 举报
回复
问题好象不是那样简单的,是否有更多的见解
liushmh 2004-08-27
  • 打赏
  • 举报
回复
仔细考虑一下,如果visitor类中要对被Visitor的对象实现多个方法的时候,你会怎么写?
按照你改写的(我在这里加了另外两个方法)
是不是会成如下形式 (此处SubVisitor1和SubVisitor2为 Visitor的两个子类)
Visitor visitor1 = new SubVisitor1();
visitor1.beginVisit(beVisited);
visitor1.visit(beVisited);
visitor1.endVisit(beVisited);

Visitor visitor2 = new SubVisitor2();
visitor2.beginVisit(beVisited);
visitor2.visit(beVisited);
visitor2.endVisit(beVisited);

而用
beVisited.accept(visitor1);
beVisited.accept(visitor2);

void accept(Visitor v)
{
v.beginVisit(this);
v.visit(this);
v.endVisit(this);
}

随着对象类型的增多,以及对被visit对象进行的操作逐步复杂,你还会觉得这两者是一样的吗?:)
ycl030379 2004-08-27
  • 打赏
  • 举报
回复
看了上面liushmh的解释,了解了一点。
其实主动和被动的关系我也想过,但我觉得这也有一点不是很成立,如果我都可以改你的代码,让你在accept函数里作什么操作的话,那我当然也一定对你有访问权的。
从编程的可理解上来说,我个人觉得visitor模式是有一些过分把visitor和beVisited的关系搞复杂了,其实如果我没有理解错的话,反而增加了它们之间的耦合,因为使用visitor模式,两个类就是相互依赖的关系了。如果只是简单的使用visitor去visit(beVisited)的话,只是单向的依赖,这样反而可以增加复用性。

至于liushmh所举的:
Visitor visitor1 = new SubVisitor1();
visitor1.beginVisit(beVisited);
visitor1.visit(beVisited);
visitor1.endVisit(beVisited);

我想完全可以不用这些麻烦,只需要担供一个allVisit(beVisited)就可以了:
allVisit(beVisited){
beginVisit(beVisited);
visit(beVisited);
endVisit(beVisited);
}

对于客户端也只是一个接口。
peakpanda 2004-08-27
  • 打赏
  • 举报
回复
呵呵,你都把人家被访问者的权利剥夺了。人家被访问者无权发表意见,访问者来决定要不要访问,这还成?
zhukejun 2004-08-26
  • 打赏
  • 举报
回复
mark一下先

50,526

社区成员

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

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