Visitor模式
Visitor模式作用是表示一个作用于某个对象结构中的各元素的操作,它使你可以在不改变各元素的类的前提下
定义作用于这些元素的新操作。
开发时,可能会经常遇到需求变更:我们做好的一个设计、实现了一个系统原型,客户又有了新的需求,因此不得不
去更该已有的设计,最常见的解决方案就是给已经设计好的类添加I新的方法去实现客户新的需求,这样就陷入了设计变更
的梦魇——不停的打补丁,带来的后果就是设计根本不可能封闭,编译永远都是整个系统代码。
在下列情况下使用Visitor模式:
1、一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依赖于其具体类的操作。
2、需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而你想避免让这些操作污染这些对象的类。
Visitor模式使得你可以将相关的操作集中起来定义在一个类中,当该对象结构被很多应用共享时,用Visitor模式让
每个应用仅包含需要用到的操作。
3、定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。改变对象结构类需要重定义对所有访问者的接口,
这可能需要很大的代价。如果对象结构类经常改变,还是在这些类中定义这些操作比较好。
C++代码示例:
<strong>//Visitor.h</strong>
#ifndef _VISITOR_H_
#define _VISITOR_H_
class ConcreteElementA;
class ConcreteElementB;
class Element;
class Visitor
{
public:
virtual ~Visitor();
virtual void
VisitConcreteElementA(Element* elm) = 0;
virtual void
VisitConcreteElementB(Element* elm) = 0;
protected:
Visitor();
private:
};
class ConcreteVisitorA:public Visitor
{
public:
ConcreteVisitorA();
virtual ~ConcreteVisitorA();
virtual void
VisitConcreteElementA(Element* elm);
virtual void
VisitConcreteElementB(Element* elm);
protected:
private:
};
class ConcreteVisitorB:public Visitor
{
public:
ConcreteVisitorB();
virtual ~ConcreteVisitorB();
virtual void
VisitConcreteElementA(Element* elm);
virtual void
VisitConcreteElementB(Element* elm);
protected:
private:
};
#endif //~_VISITOR_H_
<strong>//Visitor.cpp</strong>
#include "Visitor.h"
#include "Element.h"
#include <iostream>
using namespace std;
Visitor::Visitor()
{
}
Visitor::~Visitor()
{
}
ConcreteVisitorA::ConcreteVisitorA()
{
}
ConcreteVisitorA::~ConcreteVisitorA()
{
}
void
ConcreteVisitorA::VisitConcreteElementA(Element* elm)
{
cout<<"i will visitConcreteElementA..."<<endl;
}
void
ConcreteVisitorA::VisitConcreteElementB(Element* elm){
cout<<"i will visit ConcreteElementB..."<<endl;
}
ConcreteVisitorB::ConcreteVisitorB(){
}
ConcreteVisitorB::~ConcreteVisitorB(){
}
void
ConcreteVisitorB::VisitConcreteElementA(Element* elm){
cout<<"i will visit ConcreteElementA..."<<endl;
}
void
ConcreteVisitorB::VisitConcreteElementB(Element* elm)
{
cout<<"i will visit ConcreteElementB..."<<endl;
}
<strong>//Element.h</strong>
#ifndef _ELEMENT_H_
#define _ELEMENT_H_
class Visitor;
class Element
{
public:
virtual ~Element();
virtual void Accept(Visitor* vis) = 0;
protected:
Element();
private:
};
class ConcreteElementA:public Element
{
public:
ConcreteElementA();
~ConcreteElementA();
void Accept(Visitor* vis);
protected:
private:
};
class ConcreteElementB:public Element
{
public:
ConcreteElementB();
~ConcreteElementB();
void Accept(Visitor* vis);
protected:
private:
};
#endif //~_ELEMENT_H_
<pre name="code" class="cpp"><strong>//Element.cpp</strong>
#include "Element.h"
#include "Visitor.h"
#include <iostream>
using namespace std;
Element::Element()
{
}
Element::~Element()
{
}
void Element::Accept(Visitor* vis)
{
}
ConcreteElementA::ConcreteElementA()
{
}
ConcreteElementA::~ConcreteElementA()
{
}
void ConcreteElementA::Accept(Visitor* vis)
{
vis->VisitConcreteElementA(this);
cout<<"visiting ConcreteElementA..."<<endl;
}
ConcreteElementB::ConcreteElementB()
{
}
ConcreteElementB::~ConcreteElementB()
{
}
void ConcreteElementB::Accept(Visitor* vis)
{
cout<<"visiting ConcreteElementB..."<<endl;
vis->VisitConcreteElementB(this);
}
</pre><strong>//main.cpp</strong><pre code_snippet_id="539471" snippet_file_name="blog_20141202_6_5198548" name="code" class="cpp">#include "Element.h"
#include "Visitor.h"
#include <iostream>
using namespace std;
int main(int argc,char* argv[]){
Visitor* vis = new ConcreteVisitorA();
Element* elm = new ConcreteElementA();
elm->Accept(vis);
return 0;
}