简介
访问者模式,表示一个对于容器中各对象的操作,它让你可以在不改变容器总对象的情况下定义一个新的操作。
UML 类图
示例
学校里有操场,教室,访问者可以为学生和老师,学生在教室学习,老师在教课,学生在操场玩耍,老师在监督,各个类请先自己思考。实现如下
访问者相关类,visitor.h
#ifndef VISITOR_H
#define VISITOR_H
#include <list>
using namespace std;
class CClassroom;
class CPlayground;
class CVisitor
{
public:
virtual void Visit(CClassroom* pClassroom) = 0;
virtual void Visit(CPlayground* pPlayground) = 0;
};
class CStudent:public CVisitor
{
public:
void Visit(CClassroom* pClassroom) ;
void Visit(CPlayground* pPlayground) ;
};
class CTeacher:public CVisitor
{
public:
void Visit(CClassroom* pClassroom) ;
void Visit(CPlayground* pPlayground) ;
};
class CPlace
{
public:
virtual void accept(CVisitor* pVisitor) = 0;
};
class CClassroom:public CPlace
{
public:
void accept(CVisitor* pVisitor);
};
class CPlayground:public CPlace
{
public:
void accept(CVisitor* pVisitor);
};
class CSchool
{
public:
void Add(CPlace* pPlace);
void Remove(CPlace* pPlace);
void Accept(CVisitor* pVisitor);
private:
list<CPlace*> m_placeContainer;
};
#endif
访问者相关类的实现,visitor.cpp
#include "visitor.h"
#include <iostream>
using namespace std;
void CStudent::Visit(CClassroom* pClassroom)
{cout<<"I'm learning here."<<endl;}
void CStudent::Visit(CPlayground* pPlayground)
{cout<<"I'm playing here."<<endl;}
void CTeacher::Visit(CClassroom* pClassroom)
{cout<<"I'm teaching here."<<endl;}
void CTeacher::Visit(CPlayground* pPlayground)
{cout<<"I'm watching here."<<endl;}
void CClassroom::accept(CVisitor* pVisitor)
{pVisitor->Visit(this);
}
void CPlayground::accept(CVisitor* pVisitor)
{pVisitor->Visit(this);
}
void CSchool::Add(CPlace* pPlace)
{m_placeContainer.push_back(pPlace);
}
void CSchool::Remove(CPlace* pPlace)
{m_placeContainer.remove(pPlace);
}
void CSchool::Accept(CVisitor* pVisitor)
{for(list<CPlace*>::iterator iter = m_placeContainer.begin(); iter != m_placeContainer.end(); ++ iter)
{(*iter)->accept(pVisitor);
}
}
客户端调用,main.cpp
#include "visitor.h"
#define SAFE_DELETE(p) if(p){delete (p); (p) = NULL;}
int main(int argc, char* argv[])
{
CSchool *pSchool = new CSchool;
CPlace* pClassroom = new CClassroom;
CPlayground* pPlayground = new CPlayground;
CVisitor* pTeacher = new CTeacher;
CVisitor* pStudent = new CStudent;
pSchool->Add(pClassroom);
pSchool->Add(pPlayground);
pSchool->Accept(pTeacher);
pSchool->Accept(pStudent);
SAFE_DELETE(pStudent);
SAFE_DELETE(pTeacher);
SAFE_DELETE(pPlayground);
SAFE_DELETE(pClassroom);
SAFE_DELETE(pSchool);
return 0;
}