访问者模式,表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
访问者模式结构图
image访问者模式基本代码
#include <iostream>
#include <list>
using namespace std;
class Element;
class ConcreteElementA;
class ConcreteElementB;
class Visitor {
public:
virtual void VisitConcreteElementA(ConcreteElementA* ca) = 0;
virtual void VisitConcreteElementB(ConcreteElementB* cb) = 0;
};
class ConcreteVisitorA : public Visitor{
public:
void VisitConcreteElementA(ConcreteElementA* ca) {
cout << "ConcreteVisitorA::VisitConcreteElementA" << endl;
}
void VisitConcreteElementB(ConcreteElementB* cb) {
cout << "ConcreteVisitorA::VisitConcreteElementB" << endl;
}
};
class ConcreteVisitorB : public Visitor{
public:
void VisitConcreteElementA(ConcreteElementA* ca) {
cout << "ConcreteVisitorB::VisitConcreteElementA" << endl;
}
void VisitConcreteElementB(ConcreteElementB* cb) {
cout << "ConcreteVisitorB::VisitConcreteElementB" << endl;
}
};
class ConcreteVisitorC : public Visitor{
public:
void VisitConcreteElementA(ConcreteElementA* ca) {
cout << "ConcreteVisitorC::VisitConcreteElementA" << endl;
}
void VisitConcreteElementB(ConcreteElementB* cb) {
cout << "ConcreteVisitorC::VisitConcreteElementB" << endl;
}
};
class Element {
public:
virtual void Accept(Visitor* visitor) = 0;
};
class ConcreteElementA : public Element {
public:
void Accept(Visitor* visitor) {
cout << "ConcreteElementA: ";
visitor->VisitConcreteElementA(this);
}
void OperationA() {
cout << "OperationA" << endl;
}
};
class ConcreteElementB : public Element {
public:
void Accept(Visitor* visitor) {
cout << "ConcreteElementB: ";
visitor->VisitConcreteElementB(this);
}
void OperationB() {
cout << "OperationB" << endl;
}
};
class ObjectStructure {
private:
list<Element* > elements;
public:
void Attach(Element* element) {
elements.push_back(element);
}
void Detach(Element* element) {
elements.remove(element);
}
void Accept(Visitor* visitor) {
for (auto e = elements.begin(); e != elements.end(); e++) {
(*e)->Accept(visitor);
}
}
};
int main() {
ObjectStructure* o = new ObjectStructure();
ConcreteElementA* ca = new ConcreteElementA();
ConcreteElementB* cb = new ConcreteElementB();
o->Attach(ca);
o->Attach(cb);
ConcreteVisitorA* cv1 = new ConcreteVisitorA();
ConcreteVisitorB* cv2 = new ConcreteVisitorB();
ConcreteVisitorC* cv3 = new ConcreteVisitorC();
o->Accept(cv1);
// ConcreteElementA: ConcreteVisitorA::VisitConcreteElementA
// ConcreteElementB: ConcreteVisitorA::VisitConcreteElementB
o->Accept(cv2);
// ConcreteElementA: ConcreteVisitorB::VisitConcreteElementA
// ConcreteElementB: ConcreteVisitorB::VisitConcreteElementB
o->Accept(cv3);
// ConcreteElementA: ConcreteVisitorC::VisitConcreteElementA
// ConcreteElementB: ConcreteVisitorC::VisitConcreteElementB
delete ca;
delete cb;
delete cv1;
delete cv2;
delete cv3;
delete o;
return 0;
}
应用场景
把数据结构和作用于数据结构上的操作之间的耦合解开,使得操作集合可以相对自由地演化。
访问者模式的目的是要把处理数据结构分离出来。如果系统可以按照算法和数据结构分开,且有比较稳定的数据结构,又有易于变化的算法的话,使用访问者模式就是比较合适的,因为访问者模式使用使得算法操作的增加变得容易。
网友评论