当你需要遍历一个对象集合(比如链表或树)并对其中所有的元素进行操作时,可以为这个集合提供一个访问者。当然,这个集合也要支持访问者才行。支持访问者的元素定义为:
- class Element
- {
- public:
- virtual void accept(Visitor*) = 0;
- };
集合里可以有各种不同类型的Element(即Element的子类),当集合接受访问时,它会遍历所有的元素,并让这些元素接受访问。
- class Collection
- {
- public:
- void accept(Visitor* visitor)
- {
- foreach (Element* element in collection)
- element->accept(visitor);
- }
- };
通常Element的子类的accept方法会简单地调用Visitor的访问方法:
- class ElementTypeOne : Element
- {
- public:
- virtual void accept(Visitor* visitor)
- {
- visitor->visitTypeOne(this);
- }
- };
- class ElementTypeTwo : Element
- {
- public:
- virtual void accept(Visitor* visitor)
- {
- visitor->visitTypeTwo(this);
- }
- };
如此一来,Visitor的定义就是:
- interface Visitor
- {
- virtual void visitTypeOne(ElementTypeOne*) = 0;
- virtual void visitTypeTwo(ElementTypeTwo*) = 0;
- };
这样客户就可以用各种不同类型的Visitor来访问这个集合了。
- class Client
- {
- void Visit(Collection* collection)
- {
- Visitor* v1 = new VisitorTypeA;
- collection->accept(v1);
- Visitor* v2 = new VisitorTypeB;
- collection->accept(v2);
- }
- };
访问者模式的优点自然是在不改变集合结构本身的前提下,提供各种新的操作。缺点就是牺牲了封装性,因为访问者需要知道结构中各元素的细节。
阅读(1772) | 评论(0) | 转发(0) |