访问者模式(Visitor),表示一个做用于某对象结构中的各元素的操做。它使你能够在不改变各元素的类的前提下定义做用于这些元素的新操做。ios
访问者模式结构图算法
访问者模式使用与数据结构相对比较稳定的系统,即数据结构和做用与结构上的操做之间的耦合解脱开,使得操做集合能够相对自由的演化。其目的,要把处理从数据结构分离开来。不少系统能够按照算法和数据结构分开,若是这样的系统有比较稳定的数据结构,又有易于变化的算法的话,使用访问者模式就是比较合适的,由于访问者模式使得算法操做的增长变得容易。反之,若是这样的系统的数据结构对象易于变化,常常要有新的数据结构对象增长进来,就不适合使用访问者模式。数据结构
访问者模式的优势就是增长新的操做很容易,由于增长新的操做就意味着增长一个新的访问者。访问者模式将有关的行为集中到一个访问者对象中。缺点是使增长新的数据结构变得困难了。this
其实,大多时候你并不须要访问者模式,但当一旦须要访问者模式时,那就是真的须要它了。spa
#include <iostream> #include <list> using namespace std; class ConcreteElementA; class ConcreteElementB; //Visitor类,为该对象结构中ConcreteElement的每个类声明一个Visit操做 class Visitor { public: virtual void VisitConcreteElementA(ConcreteElementA *concreteElementA)=0; virtual void VisitConcreteElementB(ConcreteElementB *concreteElementB)=0; }; //ConcreteVisitor1和ConcreteVisitor2类,具体访问者,实现每一个由Visitor声明的操做。每一个操做实现算法的一部分, //而该算法片断乃是对应于结构中对象的类。 class ConcreteVisitor1:public Visitor { public: void VisitConcreteElementA(ConcreteElementA *concreteElementA) { cout << "ConcreteElementA被ConcreteVisitor1访问" << endl; } void VisitConcreteElementB(ConcreteElementB *concreteElementB) { cout << "ConcreteElementB被ConcreteVisitor1访问" << endl; } }; class ConcreteVisitor2:public Visitor { public: void VisitConcreteElementA(ConcreteElementA *concreteElementA) { cout << "ConcreteElementA被ConcreteVisitor2访问" << endl; } void VisitConcreteElementB(ConcreteElementB *concreteElementB) { cout << "ConcreteElementB被ConcreteVisitor2访问" << endl; } }; //Element类,定义一个Accept操做,它以一个访问者为参数 class Element { public: virtual void Accept(Visitor *visitor)=0; }; //ConcreteElementA和ConcreteElementB类,具体元素,实现Accept操做 class ConcreteElementA:public Element { public: //充分利用双分派技术,实现处理与数据结构的分离 void Accept(Visitor *visitor) { visitor->VisitConcreteElementA(this); } void OperationA() { cout << "具体元素A的其余相关方法" << endl; } }; class ConcreteElementB:public Element { public: //充分利用双分派技术,实现处理与数据结构的分离 void Accept(Visitor *visitor) { visitor->VisitConcreteElementB(this); } void OperationA() { cout << "具体元素B的其余相关方法" << endl; } }; //ObjectStructure类,能枚举它的元素,能够提供一个高层的接口以容许访问者访问它的元素 class ObjectStructure { private: list<Element*> m_list; public: void Attach(Element *element) { m_list.push_back(element); } void Detach(Element *element) { m_list.remove(element); } void Accept(Visitor *visitor) { list<Element*>::iterator iter; for(iter=m_list.begin();iter!=m_list.end();iter++) { if(*iter!=NULL) (*iter)->Accept(visitor); } } }; int main() { ObjectStructure *o=new ObjectStructure(); o->Attach(new ConcreteElementA()); o->Attach(new ConcreteElementB()); ConcreteVisitor1 *v1=new ConcreteVisitor1(); ConcreteVisitor2 *v2=new ConcreteVisitor2(); o->Accept(v1); o->Accept(v2); return 0; }
一般ConcreteVisitor能够单独开发,没必要跟ConcreteElementA或ConcreteElementB写在一块儿。正由于这样,ConcreteVisitor能提升ConcreteElement之间的独立性,若是把一个处理动做设计成ConcreteElementA和ConcreteElementB类的方法,每次想新增“处理”以扩充功能时就得去修改ConcreteElementA和ConcreteElementB了。设计
下面是关于男人和女人的访问者模式例子code
#include <iostream> #include <list> using namespace std; class Man; class Woman; class Action { public: virtual void GetManConclusion(Man *concreteElementA)=0; virtual void GetWomanConclusion(Woman *concreteElementB)=0; }; class Person { public: //获取状态对象 virtual void Accept(Action *visiton)=0; }; //这里的关键在于只分为男人和女人,这个性别的分类是稳定的,因此能够在状态类镇南关,增长“男人反应”和“女人反映”两个方法,方法个数 //是稳定的,不会很容易的发生变化。而“人”抽象类中有一个抽象方法“接受”,它是用来得到“状态”对象的。每一种具体状态都继承“状态” //抽象类,实现两个反应方法 class Success:public Action { public: void GetManConclusion(Man *concreteElementA) { cout << "男人成功时,背后多半有一个伟大的女人。" << endl; } void GetWomanConclusion(Woman *concretementB) { cout << "女人成功时,背后大多有一个不成功的男人。" << endl; } }; class Failing:public Action { public: void GetManConclusion(Man *concreteElementA) { cout << "男人失败时,闷头喝酒,谁也不用劝。" << endl; } void GetWomanConclusion(Woman *concretementB) { cout << "女人失败时,眼泪汪汪,谁也劝不了。" << endl; } }; class Amativeness:public Action { public: void GetManConclusion(Man *concreteElementA) { cout << "男人恋爱时,凡是不懂也要装懂。" << endl; } void GetWomanConclusion(Woman *concretementB) { cout << "女人恋爱时,遇事懂也装做不懂。" << endl; } }; class Man:public Person { public: void Accept(Action *visitor) { visitor->GetManConclusion(this); } }; class Woman:public Person { public: void Accept(Action *visiton) { visiton->GetWomanConclusion(this); } }; //对象结构 class ObjectStructure { private: list<Person*> m_list; public: void Attach(Person *element) { m_list.push_back(element); } void Detach(Person *element) { m_list.remove(element); } void Display(Action *visitor) { list<Person*>::iterator iter=m_list.begin(); for(;iter!=m_list.end();iter++) { if(NULL!=*iter) (*iter)->Accept(visitor); } } }; int main() { ObjectStructure *o=new ObjectStructure(); o->Attach(new Man()); o->Attach(new Woman()); Success *v1=new Success(); o->Display(v1); Failing *v2=new Failing(); o->Display(v2); Amativeness *v3=new Amativeness(); o->Display(v3); return 0; }