visitor(访问者)——类行为模式
1.意图
表示一个作用于某对象结构中的各个元素的操作。他使你可以在不改变各元素的前提下定义作用于这些元素的新操作。2.动机操作需要对不同的数据类型做不同的处理。将每一个类中相关的操作包装成一个对象,并在需要时将此对象传递给当前访问的元素,当元素接收访问者时,向访问者发送一个包含自身类信息的请求。该请求将自身作为一个参数。然后访问者将对这个元素执行操作——这一操作以前是在该元素的类中的。
3.适用性1)一个对象结构包含很多对象,他们有不同的接口,而你想对这些对象实施一些依赖于其具体类的操作。2)需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而你想避免让这些操作污染整个对象的类。3)定义对象结构的类改变很少,但是需要再此结构上定义新的操作。
4.结构
参考:
5.参与者visitor访问者为该对象结构中每一个concreteElement的每一个类声明一个visit操作。该操作的名字和特征标示了发送visit请求给该访问者的那个类concreteVisitor具体访问者实现每一个由visitor声明的操作。每个操作实现本算法的一部分,而该算法片段乃是对应于结构中对象的类element元素定义一个accept操作,他以一个访问者为参数objectStructure对象结构能枚举他的元素可以提供一个高层的接口以允许该访问者访问它的元素可以是一个复合或者一个集合
6.协作一个visitor模式的客户必须创建一个concreteVisitor对象,然后遍历该对象结构,并用访问者访问每一个元素。当一个元素被访问时,他调用对应于它的类的visitor操作。如果必要,该元素将自身作为这个操作的一个参数以便该访问者访问它的状态。
7.效果1)访问者模式使得易于增加新的操作2)访问者集中相关的操作而分离无关的操作3)增加新的concreteElement很困难4)通过类层次进行访问5)累积状态6)破坏封装
8.实现每个对象结构都有一个相关的visitor类。这个抽象的访问者类为定义对象结构的每一个concreteElement类声明一个visitConcreteElement操作。
9.代码示例
#include#include #include
using namespace std;class visitor;class element{ public: virtual void accept(visitor *vi)=0; string getName() { return name; } int getSalary() { return salary; } protected: string name; int salary;};class employee:public element{ public: employee(string _name, int _salary) { name = _name; salary = _salary; } void accept(visitor *vi);};class boss:public element{ public: boss(string _name, int _salary) { name = _name; salary = _salary; } void accept(visitor *vi);};class visitor{ public: virtual void visit(employee *ele){} virtual void visit(boss *ele){}};class elementVisitor:public visitor{ public: void visit(employee *ele) { cout< getName()<<" : "< getSalary()< getName()<<" : "< getSalary()< visit(this);}void boss::accept(visitor *vi){ vi->visit(this);}class company{ private: list elist; public: void attach(element *ele) { elist.push_back(ele); } void dettach(element *ele) { list ::iterator ite = find(elist.begin(), elist.end(), ele); elist.erase(ite); } void accept(visitor *vi) { for(list ::iterator ite = elist.begin(); ite!=elist.end(); ite++) { (*ite)->accept(vi); } }};int main(){ visitor *vi = new elementVisitor(); employee *e = new employee("lilei", 1000); e->accept(vi); boss *b = new boss("Hanmeimei", 100000); b->accept(vi); cout< <<"list : "< attach(ea); com->attach(eb); com->attach(ec); com->attach(ba); com->attach(bb); com->accept(vi); cout< <<"lei left :"< dettach(ba); com->accept(vi);}
10.相关模式
composite访问者可以用于对一个由composite模式定义的对象结构进行操作interpreter访问者可以用于解释