UML类图(仅供参考)如下:
访问者模式解决的问题:
我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作。主要将数据结构与数据操作分离。稳定的数据结构和易变的操作耦合问题。
源码
#include <list>
#include <iostream>
class CAction;
// 抽象访问者
class CVisitor
{
public:
virtual ~CVisitor() {}
// 接收状态,并作出相应反应
virtual void Accept(CAction *pAction) = 0;
};
// 抽象状态
class CAction
{
public:
virtual ~CAction() {}
// A访问者的反应
virtual void GetVisitorA(CVisitor *pVistor) = 0;
// B访问者的反应
virtual void GetVisitorB(CVisitor *pVistor) = 0;
// 有限的访问者,且个数不多
//virtual void GetVisitor...(CVisitor *pVistor) = 0;
};
// 访问者A
class CVisitorA :public CVisitor
{
virtual void Accept(CAction *pAction)
{
pAction->GetVisitorA(this);
}
};
// 访问者B
class CVisitorB :public CVisitor
{
virtual void Accept(CAction *pAction)
{
pAction->GetVisitorB(this);
}
};
// 第一种状态
class CAction1 :public CAction
{
public:
virtual void GetVisitorA(CVisitor *pVistor)
{
std::cout << "访问者A觉得第一种状态好辣" << std::endl;
}
virtual void GetVisitorB(CVisitor *pVistor)
{
std::cout << "访问者B觉得第一种状态好咸" << std::endl;
}
};
// 第二种状态
class CAction2 :public CAction
{
public:
virtual void GetVisitorA(CVisitor *pVistor)
{
std::cout << "访问者A觉得第二种状态好高" << std::endl;
}
virtual void GetVisitorB(CVisitor *pVistor)
{
std::cout << "访问者B觉得第二种状态好长" << std::endl;
}
};
// 第三种状态
class CAction3 :public CAction
{
public:
virtual void GetVisitorA(CVisitor *pVistor)
{
std::cout << "访问者A觉得第三种状态好美" << std::endl;
}
virtual void GetVisitorB(CVisitor *pVistor)
{
std::cout << "访问者B觉得第三种状态好丑" << std::endl;
}
};
class CVisitorList
{
public:
void AddVisitor(CVisitor *visitor)
{
m_listVisitor.push_back(visitor);
}
void Accept(CAction *pAction)
{
for (auto &var : m_listVisitor)
{
var->Accept(pAction);
}
}
private:
std::list<CVisitor*> m_listVisitor;
};
int main()
{
// 两个访问者对象
CVisitorA visitorA;
CVisitorB visitorB;
// 访问者管理对象
CVisitorList visitorList;
visitorList.AddVisitor(&visitorA);
visitorList.AddVisitor(&visitorB);
// 不确定种类个数的状态对象
CAction1 action1;
visitorList.Accept(&action1);
CAction2 action2;
visitorList.Accept(&action2);
CAction3 action3;
visitorList.Accept(&action3);
return 0;
}
好处
1、符合单一职责原则。
2、优秀的扩展性。
3、灵活性