乐趣区

访问者模式

简介

访问者模式,表示一个对于容器中各对象的操作,它让你可以在不改变容器总对象的情况下定义一个新的操作。

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;
}
退出移动版