
正文
Visitor Pattern
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
1.Visitor模式:将更新(变更)封装到一个类中(访问操作),并由待更改类提供一个接收接口,则可在不破坏类的前提下,为类提供增加新的新操作。
2.Visitor模式结构图

Visitor模式的关键是双分派(Double-Dispatch)的技术:Accept()操作是一个双分派的操作,具体调用哪个Accept()操作,有两个决定因素(1)Element类型(2)Visitor类型。
3.实现
#ifndef _VISITOR_H_
#define _VISITOR_H_ class Element; class Visitor
{
public:
virtual ~Visitor();
virtual void VisitConcreteElementA(Element* elm) = ;
virtual void VisitConcreteElementB(Element* elm) = ;
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
#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 visit ConcreteElementA..."<<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;
}
Visitor.cpp
#ifndef _ELEMENT_H_
#define _ELEMENT_H_ class Visitor; class Element
{
public:
virtual ~Element();
virtual void Accept(Visitor* vis) = ;
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
#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);
}
Element.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 ;
}
main.cpp
4.Visitor模式的缺点
(1)破坏了封装性
(2)ConcreteElement的扩展很困难:每增加一个Element的子类,就要修改Visitor的接口,使得可以提供给这个新增加的子类的访问机制。






