设计模式二十四:visitor(访问者)——类行为模式

visitor(访问者)——类行为模式

 

1.意图
表示一个作用于某对象结构中的各个元素的操作。他使你可以在不改变各元素的前提下定义作用于这些元素的新操作。

 


2.动机
操作需要对不同的数据类型做不同的处理。
将每一个类中相关的操作包装成一个对象,并在需要时将此对象传递给当前访问的元素,当元素接收访问者时,向访问者发送一个包含自身类信息的请求。该请求将自身作为一个参数。然后访问者将对这个元素执行操作——这一操作以前是在该元素的类中的。

 


3.适用性
1)一个对象结构包含很多对象,他们有不同的接口,而你想对这些对象实施一些依赖于其具体类的操作。
2)需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而你想避免让这些操作污染整个对象的类。
3)定义对象结构的类改变很少,但是需要再此结构上定义新的操作。

 


4.结构

参考:http://www.cnblogs.com/aspnet2008/archive/2009/02/11/1386743.html

 


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<iostream>
#include<list>
#include<string>
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<<ele->getName()<<" : "<<ele->getSalary()<<endl;
    }
    void visit(boss *ele)
    {
        cout<<ele->getName()<<" : "<<ele->getSalary()<<endl;
    }
};

void employee::accept(visitor *vi)
{
    vi->visit(this);
}
void boss::accept(visitor *vi)
{
    vi->visit(this);
}

class company
{
    private:
    list<element *> elist;
    public:
    void attach(element *ele)
    {
        elist.push_back(ele);
    }
    void dettach(element *ele)
    {
        list<element *>::iterator ite = find(elist.begin(), elist.end(), ele);
        elist.erase(ite);
    }
    void accept(visitor *vi)
    {
        for(list<element *>::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<<endl<<"list : "<<endl;
    employee *ea = new employee("weihua", 3400);
    employee *eb = new employee("lily", 123400);
    employee *ec = new employee("lucy", 11200);
    boss *ba = new boss("lei", 106671);
    boss *bb = new boss("jiong", 109811);
    company *com = new company();
    com->attach(ea);
    com->attach(eb);
    com->attach(ec);
    com->attach(ba);
    com->attach(bb);
    com->accept(vi);
    
    cout<<endl<<"lei left :"<<endl;
    com->dettach(ba);
    com->accept(vi);
}

 

 

10.相关模式
composite访问者可以用于对一个由composite模式定义的对象结构进行操作
interpreter访问者可以用于解释

 

 

posted @ 2012-05-23 20:24  w0w0  阅读(331)  评论(0编辑  收藏  举报