在开发时有时会遇到需求变动,这样就要经常去修改已有的设计.比较常见的是在实现好的类中添加新方法客户新需求.这时可以使用Visitor模式.
Visitor模式则提供了一种解决方案:将更新封装到一个类中,并由待更改类提供一个接收接口,来实现目的.
这里对对象(concreteElement)添加了一个统一的接口:Accept函数,来接收一个访问者对象.通过参数Visitor把对对象的操作移到类外,通过调用Visitor的接口函数visitConcreElement针对当前对象进行操作.
函数Accept()是个双分派操作.调用哪一个Accept由Element类型和Visitor类型决定.
//Visitor.h
ifndef _VISITOR_H_
#define _VISITOR_H_
class ConcreteElementA;
class ConcreteEnementB;
class Element;
class Visitor
{
public:
virtual ~Visitor();
virtual void VisitConcreteElementA(Element* elm) = 0;
virtual void VisitConcreteElementB(Element* eml) = 0;
protected:
Visitor();
};
class ConcreteVisitorA :public Visitor
{
public:
ConcreteVisitorA();
virtual ~ConcreteVisitorA();
virtual void VisitConcreteElementA(Element* elm) ;
virtual void VisitConcreteElementB(Element* eml) ;
};
class ConcreteVisitorB :public Visitor
{
public:
ConcreteVisitorB();
virtual ~ConcreteVisitorB();
virtual void VisitConcreteElementA(Element* elm);
virtual void VisitConcreteElementB(Element* eml);
};
#endif
//Visitor.cpp
#include "Visitor.h"
#include "Element.h"
#include <iostream>
Visitor::Visitor()
{}
Visitor::~Visitor()
{}
ConcreteVisitorA::ConcreteVisitorA()
{}
ConcreteVisitorA::~ConcreteVisitorA()
{}
void ConcreteVisitorA::VisitConcreteElementA(Element* elm)
{
std::cout << "i will visit ConcreteElementA." << std::endl;
}
void ConcreteVisitorA::VisitConcreteElementB(Element* elm)
{
std::cout << "i will visit ConcreteElementB." << std::endl;
}
ConcreteVisitorB::ConcreteVisitorB()
{}
ConcreteVisitorB::~ConcreteVisitorB()
{}
void ConcreteVisitorB::VisitConcreteElementA(Element* elm)
{
std::cout << "i will visit ConcreteElementA." << std::endl;
}
void ConcreteVisitorB::VisitConcreteElementB(Element* elm)
{
std::cout << "i will visit ConcreteElementB." << std::endl;
}
//Element.h
#ifndef _ELEMENT_H_
#define _ELEMENT_H_
class Visitor;
class Element
{
public:
virtual ~Element();
virtual void Accept(Visitor* vis) = 0;
protected:
Element();
};
class ConcreteElementA :public Element
{
public:
ConcreteElementA();
~ConcreteElementA();
void Accept(Visitor* vis);
};
class ConcreteElementB :public Element
{
public:
ConcreteElementB();
~ConcreteElementB();
void Accept(Visitor* vis);
};
#endif
//Element.cpp
#include "Element.h"
#include "Visitor.h"
#include <iostream>
Element::Element()
{}
Element::~Element()
{}
void Element::Accept(Visitor* vis)
{}
ConcreteElementA::ConcreteElementA()
{}
ConcreteElementA::~ConcreteElementA()
{}
void ConcreteElementA::Accept(Visitor* vis)
{
vis->VisitConcreteElementA(this);
std::cout << "visiting ConcreteElementA." << std::endl;
}
ConcreteElementB::ConcreteElementB()
{}
ConcreteElementB::~ConcreteElementB()
{}
void ConcreteElementB::Accept(Visitor* vis)
{
vis->VisitConcreteElementB(this);
std::cout << "visiting ConcreteElementB." << std::endl;
}
//main.cpp
#include "Element.h"
#include "Visitor.h"
#include <iostream>
int main()
{
Visitor* vis = new ConcreteVisitorA();
Element* elm = new ConcreteElementA();
elm->Accept(vis);
return 0;
}