我读了一本关于访问者模式。 它提供了相同的类图在oodesign的网站 。
它说,增加新的ConcreteElement类是很难的。 但我不明白为什么。 正如我理解的,Concretevisitor定义了一组操作,这必须由concreteElement可以使用的。 所以,当我添加一个新的元素,里面有我前面定义的相同的操作,我不需要添加任何东西(不仅仅是ConcreteElement本身)。 如果我添加新元素,它没有我刚才在游客中定义相同的操作,我需要添加一个新的访问者。 但是,这我必须在任何设计模式做。
那么,你必须扩展所有的访问者。
你有一个来电者,一些内容需要进行访问,和元素 - 游客 - 这确实单个元素的处理。 你的目标是保持要素的实施和固定主叫方,并通过新的访问者扩展功能。
通常你有很多具体的参观者。 如果您添加要处理的新类型的元素,你将需要改变所有的混凝土游客考虑到这一点。
为什么?
那么,想象调用者是“工厂”,你具备的要素“车”和“自行车”。
对于操作“画图”你必须有方法
void process(Car c); // Paint a car
void process(Bike b); // Paint a bike
同样地,对于操作“组装”,“包”,“洗”等。
如果添加元素“滑板车”,所有的操作必须用一种新的方法来延长
void process(Scooter s); // Handle a Scooter
这是一些工作。 您还可能会碰到ISSE在您添加的元素是你canøt轻松地适应他们的操作别人如此不同。
维基百科(http://en.wikipedia.org/wiki/Visitor_pattern)说:
在本质上,访问者允许一个不修改类本身新的虚拟功能添加到一个类家族; 相反,一个创建了实现所有的虚拟功能的适当专业化的访问者类。 参观者需要实例的引用作为输入,并通过实现双重派遣的目标。
这是说什么我尝试上面说的一个非常抽象的方式。 通常你会这些方法添加的元素,但如果你不能,你必须添加方法,否则somethign,并通过沿做处理。 这是一些额外的工作,但可能是值得的,如果情况值得它。
这在SO问题来到了刚刚结束。 要引用自己这个问题,更具体的讨论
究其原因不改变组实体(你访问类)的前提条件是,因为它迫使你实现每个具体的访问者一个新的visitXYZ。 但我从来没有花太多的股票在推理becasue如果要支持一个持久性游客和文本搜索的访问者,并打印访客,并验证访客,你去加你会想实现所有新的实体功能反正。 访问者模式(与公共基类)只是让编译器找到你忘了为实现你的人。
所以,是的,它经常说,它很难实现另外conrete要素(或实体),但在我看来,这是一派胡言。
如果你添加一个新的混凝土构件,那么你所有的访问者类将需要添加一个新的visit
方法的新元素。 如果您没有使用用户时,你就必须在等效方法反正添加到您的新的混凝土构件。
但添加到每个访问者的新方法可能比添加相当于一套方法到一个新的元素类更难。 其原因是,游客往往需要遍历元素树结构,可能需要管理自己的状态的数据,因为它这样做。 添加一个新的visit
方法可能需要修改其中涉及思考新方法如何与现有的相互作用时的状态数据visit
方法的其他元素。
这可能是简单的等效方法添加到您的新的元素类,如果你没有观众,因为你只需要担心这是更有凝聚力新的混凝土构件的内部状态。
从本质上讲,访问者模式是一种数据的机械手,它会
- 下面的一些规则元素之间穿越
- 做一些计算和处理这些元素提供数据
在一个字,访问者模式将扩展系统功能,而无需触摸元件类定义。
但这是否意味着,如果添加了新的混凝土构件类访问者类必须进行修订? 这要看,我相信,在访问者模式是如何设计和实施。
如果单独所有访客的访问方式访问到函子,并动态将它们结合在一起,那么它可能延长如何系统时,对于游客和visitee更容易。
这是我几年前写访问者模式的实现,代码是有点老了,不擦得干干净净,但不知何故工程:)
https://github.com/tezheng/visitor