访问者模式
访问者模式的目的是封装一些施加于某种数据结构元素之上的操作。一旦这些操作需要修改的话,接受这个操作的数 据结构可以保持不变。访问者模式适用于数据结构相对未定的系统,它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可 以相对自由的演化。访问者模式使得增加新的操作变的很容易,就是增加一个新的访问者类。访问者模式将有关的行为集中到一个访问者对象 中,而不是分散到一个个的节点类中。当使用访问者模式时,要将尽可能多的对象浏览逻辑放在访问者类中,而不是放到它的子类中。访问者模式可以跨过几个类的等级结构访问属于不同的等级结构的成员类。
#include <iostream>
#include <list>
using namespace std;
class ParkElement;
class Visitor{
public:
virtual ~Visitor(){}
virtual void visit(ParkElement *parkElement)=0;
};
class ParkElement
{
public:
virtual ~ParkElement(){}
virtual void accept(Visitor* visitor)=0;
virtual string getName()=0;
};
class ParkA : public ParkElement
{
public:
virtual ~ParkA(){}
virtual void accept(Visitor* visitor){
visitor->visit(this);
}
virtual string getName(){
return "ParkA";
}
};
class ParkB : public ParkElement
{
public:
virtual ~ParkB(){}
virtual void accept(Visitor *visitor){
visitor->visit(this);
}
virtual string getName(){
return "parkB";
}
};
class Park : public ParkElement
{
public:
Park(){
parks.clear();
}
void setParkElement(ParkElement* pe){
parks.push_back(pe);
}
string getName()
{
return "Park";
}
virtual void accept(Visitor *visitor){
for(list<ParkElement*>::iterator it=parks.begin(); it!=parks.end();it++)
{
visitor->visit((*it));
}
}
private:
list<ParkElement*> parks;
};
class VisitorA : public Visitor
{
public:
virtual ~VisitorA(){}
virtual void visit(ParkElement *parkElement){
std::cout << "visitorA" <<parkElement->getName()<< std::endl;
}
};
class VisitorB : public Visitor
{
public:
virtual ~VisitorB(){}
virtual void visit(ParkElement *parkElement){
std::cout << "visitorB" <<parkElement->getName()<< std::endl;
}
};
class VisitorManager : public Visitor
{
public:
virtual ~VisitorManager(){}
virtual void visit(ParkElement *parkElement){
std::cout << "VisitorManager" <<parkElement->getName()<< std::endl;
}
};
void test1()
{
Visitor *va = new VisitorA();
Visitor *vb = new VisitorB();
ParkElement *pa = new ParkA();
ParkElement *pb = new ParkB();
pa->accept(va);
pb->accept(vb);
delete va;
delete vb;
delete pa;
delete pb;
}
void test2()
{
ParkElement *pa = new ParkA();
ParkElement *pb = new ParkB();
Park *p = new Park();
p->setParkElement(pa);
p->setParkElement(pb);
Visitor *vm = new VisitorManager();
p->accept(vm);
delete pb;
delete pa;
delete vm;
delete p;
}
int main()
{
test1();
test2();
return 0;
}