访问者模式

访问者模式



#include <iostream>
using namespace std;
class Element;
 
class Visitor
{
public:
    virtual ~Visitor(){}
    virtual void visitConElemA(Element* elm)=0;
    virtual void visitConElemB(Element* elm)=0;
protected:
    Visitor(){}
};
 
 
class ConcreteVisitorA:public Visitor
{
public:
    ConcreteVisitorA(){};
    virtual ~ConcreteVisitorA(){};
    void visitConElemA(Element* elm){cout<<"visit A";}
    void visitConElemB(Element* elm){cout<<"visit B";}
};
 
 
class ConcreteVisitorB:public Visitor
{
public:
    ConcreteVisitorB(){};
    virtual ~ConcreteVisitorB(){};
    void visitConElemA(Element* elm){cout<<"visit A";}
    void visitConElemB(Element* elm){cout<<"visit B";}
};
 
 
class Element
{
public:
    virtual ~Element(){};
    virtual void Accept(Visitor* vis)=0;
protected:
    Element(){};
};
 
 
class ConcreteElementA:public Element
{
public:
    ConcreteElementA(){}
    ~ConcreteElementA(){}
    void Accept(Visitor* vis)
    {
        cout<<"This is A interface "<<endl; vis-="">visitConElemA(this);
    }
};
 
 
class ConcreteElementB:public Element
{
public:
    ConcreteElementB(){}
    ~ConcreteElementB(){}
    void Accept(Visitor* vis)
    {
        cout<<"This is B interface ";
        vis->visitConElemB(this); 
    }
};
 
 
void main()
{
    Visitor* vis=new ConcreteVisitorA();
    Element* elm=new ConcreteElementA();
    elm->Accept(vis);
 
    delete elm;
    delete vis;
}

1 主要优点

  (1)增加新的访问操作十分方便, 符合开闭原则

  (2)将有关元素对象的访问行为集中到一个访问者对象中,而不是分散在一个个的元素类中,类的职责更加清晰 => 符合单一职责原则

2 主要缺点

  (1)增加新的元素类很困难,需要在每一个访问者类中增加相应访问操作代码 => 违背了开闭原则

  (2)元素对象有时候必须暴露一些自己的内部操作和状态,否则无法供访问者访问 => 破坏了元素的封装性

3 应用场景

  (1)一个对象结构包含多个类型的对象,希望对这些对象实施一些依赖其具体类型的操作。=> 不同的类型可以有不同的访问操作

  (2)对象结构中对象对应的类很少改变 很少改变 很少改变(重要的事情说三遍),但经常需要在此对象结构上定义新的操作。