意图:GOF的书上有这样的描述:表示一个作用于某对象结构中的各个元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
类图结构:
演示模型和代码:
这里的访问者是水费收费员(VisitorWater)和电费收费员(VisitorElectric),对象结构是整个村庄(Village), 各元素为各个具体家庭((小华家)FamilyXiaoHua、(小明家)FamilyXiaoMing,(李宁家)FamilyLiNing ) 。其实看完这个实例的代码就可以大体理解上面意图中的描述了:"作用于对象结构中的对各个元素额操作",这里的对各个元素的操作其实就是定义在基类Visitor中的各个接口,“它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作",这句话其实是通过定义具体的访问者并实现自定义的具体接口来实现的。
#include <iostream>
#include <string>
using namespace std;
class FamilyXiaoHua;
class FamilyXiaoMing;
class FamilyLiNing;
class Visitor;
class Family
{
public:
Family(std::string name){
m_name = name;
}
virtual ~Family(){}
std::string name() { return m_name; }
protected:
virtual void Accept(Visitor* visitor) = 0;
protected:
std::string m_name;
};
class Visitor
{
public:
Visitor() {}
virtual ~Visitor() {}
virtual void visitFamilyXiaoHua(FamilyXiaoHua* fxh)
{
}
virtual void visitFamilyXiaoMing(FamilyXiaoMing* fxm)
{
}
virtual void visitFamilyLiNing(FamilyLiNing* flm)
{
}
private:
};
class FamilyXiaoHua : public Family
{
public:
FamilyXiaoHua(): Family("FamilyXiaoHua"){
}
~FamilyXiaoHua() {}
friend class Village;
private:
virtual void Accept(Visitor* visitor);
};
void FamilyXiaoHua::Accept(Visitor* visitor) {
visitor->visitFamilyXiaoHua(this);
}
class FamilyXiaoMing : public Family
{
public:
FamilyXiaoMing() : Family("FamilyXiaoMing"){
}
~FamilyXiaoMing(){}
friend class Village;
private:
virtual void Accept(Visitor* visitor);
};
void FamilyXiaoMing::Accept(Visitor* visitor) {
visitor->visitFamilyXiaoMing(this);
}
class FamilyLiNing : public Family
{
public:
FamilyLiNing() : Family("FamilyLiNing") {
}
~FamilyLiNing(){}
friend class Village;
private:
virtual void Accept(Visitor* visitor);
};
void FamilyLiNing::Accept(Visitor* visitor) {
visitor->visitFamilyLiNing(this);
}
class Village
{
public:
Village(FamilyXiaoHua *fxh,FamilyXiaoMing *fxm,
FamilyLiNing *fln){
m_fxh = fxh;
m_fxm = fxm;
m_fln = fln;
}
~Village(){
if (m_fxh) delete m_fxh;
if (m_fxm) delete m_fxm;
if (m_fln) delete m_fln;
}
void Accept(Visitor *visitor)
{
m_fxh->Accept(visitor);
m_fxm->Accept(visitor);
m_fln->Accept(visitor);
}
private:
FamilyXiaoHua* m_fxh;
FamilyXiaoMing* m_fxm;
FamilyLiNing* m_fln;
};
class VisitorWater : public Visitor
{
public:
VisitorWater(){
}
~VisitorWater(){}
virtual void visitFamilyXiaoHua(FamilyXiaoHua* fxh)
{
cout << "This is VisitorWater to visit " << fxh->name() << endl;
}
virtual void visitFamilyXiaoMing(FamilyXiaoMing* fxm)
{
cout << "This is VisitorWater to visit " << fxm->name() << endl;
}
virtual void visitFamilyLiNing(FamilyLiNing* flm)
{
cout << "This is VisitorWater to visit " << flm->name() << endl;
}
private:
};
class VisitorElectric : public Visitor
{
public:
VisitorElectric(){
}
~VisitorElectric(){}
virtual void visitFamilyXiaoHua(FamilyXiaoHua* fxh)
{
cout << "This is VisitorElectric to visit " << fxh->name() << endl;
}
virtual void visitFamilyXiaoMing(FamilyXiaoMing* fxm)
{
cout << "This is VisitorElectric to visit " << fxm->name() << endl;
}
virtual void visitFamilyLiNing(FamilyLiNing* flm)
{
cout << "This is VisitorElectric to visit " << flm->name() << endl;
}
private:
};
int main(int argc, char *argv[])
{
FamilyXiaoHua *fxh = new FamilyXiaoHua();
FamilyXiaoMing *fxm = new FamilyXiaoMing();
FamilyLiNing* flm = new FamilyLiNing();
Village* village = new Village(fxh, fxm, flm);
VisitorWater* visitorW = new VisitorWater();
VisitorElectric* visitorE = new VisitorElectric();
village->Accept(visitorW);
village->Accept(visitorE);
return 0;
}
运行输出:
此模式的优缺点:
1.访问者模式使得易于增加新的操作;
2.访问者集中相关的操作而分离无关的操作;
3.增加新的ConcreteElement类很困难;
4.通过类层次进行访问;
5.累积状态;
6.破坏封装;