我读了一本关于访问者模式的书。它给出了与oodesign's website中相同的类图。
它说添加新的ConcreteElement类很难。但我不明白为什么。据我所知,具体访问者定义了一组操作,这些操作必须由concreteElement使用。因此,当我添加一个新元素时,我不需要添加任何东西(只需要添加ConcreteElement本身)。如果我添加一个新元素,它没有我之前在访问者中定义的相同操作,我需要添加一个新访问者。但在任何设计模式中我都必须这样做。
发布于 2012-06-28 19:12:33
好吧,你必须延长你所有的访客。
您有一个调用者、一些需要访问的元素和一个处理单个元素的元素-访问者。您的目标是保持元素和调用者的实现固定不变,并通过新访问者扩展功能。
通常情况下,你会有很多混凝土访问者。如果添加要处理的新类型的元素,则需要更改所有的具体访问者以考虑这一点。
为什么?
想象一下,调用者是"Factory",您有元素"Car“和"Bike”。
对于“画图”操作,你必须有方法
void process(Car c); // Paint a car
void process(Bike b); // Paint a bike操作"Assemble“、"Package”、"Wash“等也是如此。
如果你添加了一个元素"Scooter",所有的操作都必须用一个新的方法来扩展
void process(Scooter s); // Handle a Scooter这是一项工作。此外,您可能会遇到isse,您添加的元素与其他元素非常不同,因此您可以很容易地将它们适合操作。
维基百科(http://en.wikipedia.org/wiki/Visitor_pattern)说
本质上,访问者允许用户在不修改类本身的情况下向类系列添加新的虚拟函数;相反,用户可以创建实现虚拟函数的所有适当专门化的访问者类。访问者将实例引用作为输入,并通过双重分派来实现目标。
这是一种非常抽象的方式来表达我试图在上面说的话。通常,您会将这些方法添加到元素中,但如果不能,则必须将这些方法添加到其他元素中,并将其传递给其他元素以进行处理。这是一些额外的工作,但如果情况值得的话,这可能是值得的。
发布于 2012-06-28 20:13:15
这是在最近的一个SO问题中提出的。引用this问题,更具体地说是discussion
不更改实体(类)集的前提条件是它迫使您在每个具体访问者中实现一个新的VisitXYZ。但我从来没有在这个推理中考虑太多,因为如果你支持一个持久化访问者,一个文本搜索访问者,一个打印访问者,一个验证访问者,你去添加一个新的实体,你无论如何都会想要实现所有这些功能。访问者模式(带有一个公共基类)只会让编译器找到您忘记为您实现的那些。
所以,是的,人们经常说很难实现附加的内容元素(或实体),但在我看来,这是一派胡言。
发布于 2012-06-28 20:27:45
如果添加一个新的具体元素,那么所有访问者类都需要为新元素添加一个新的visit方法。如果你没有使用访问者,你将不得不添加等价的方法到你的新的具体元素。
但是,向每个访问者添加一个新方法可能比向一个新的element类添加等价的方法集更难。原因是访问者经常需要遍历元素树结构,并且可能需要管理自己的状态数据。添加新的visit方法可能需要修改状态数据,这涉及到考虑新方法如何与其他元素的现有visit方法交互。
如果你没有访问者,向你的新元素类添加等价的方法可能会更简单,因为你只需要担心新的混凝土元素的内部状态,它更有内聚力。
https://stackoverflow.com/questions/11241761
复制相似问题