C++ 设计模式 —— 22.访问者模式
2020-01-16 本文已影响0人
JeremyYv
-
访问者模式:一种行为型设计模式
-
应用场景:
一个对象由很多部分组成,对这个对象的操作会对各部分依次操作。而在不同情景下,对各部分操作也不同。
为了新增操作时无需了解对象内部结构,且具备可扩展性,将操作抽离为访问者类,类中实现对各部分具体的操作方法。
然后在对象中提供一个接口用以访问者访问,在该接口总,对象会调用访问者中对应各部分的操作方法,操作对象中的各部分。 -
举例:
一台电脑中有很多组件,CPU、GPU、硬盘。维修人员对电脑进行整体维修时,需要对各部件依次进行维修,而且每部件具体的维修方式不同。不同的维修人员对相同的部件维修方式可能也不同。
维修人员就是访问者。访问者类中实现了针对不同部件的维修方式。
电脑就是被访问者。被访问者提供访问接口,使用访问者类中实现的不同部件维修方式,对内部部件进行访问。
以下是访问者模式的简单代码实现
#include <iostream>
#include <list>
using namespace std;
class Visitor;
//组成Computer的各组件基类
class Element
{
public:
Element(string strName):m_strName(strName){}
string GetName()
{
return m_strName;
}
//组件接受访问者访问的接口
virtual void AcceptVisitor(Visitor* pVisitor) = 0;
private:
//组件的标识名称
string m_strName;
};
//访问者基类,针对不同组件,提供不同的访问接口
class Visitor
{
public:
virtual void VisitCPU(Element* pEle) = 0;
virtual void VisitGPU(Element* pEle) = 0;
virtual void VisitDISK(Element* pEle) = 0;
};
//Computer类,由各组件组成,访问者访问Computer时将依次访问各组件
class Computer
{
public:
~Computer()
{
for(Element* pElement: m_listEle)
{
delete pElement;
}
}
void AddElement(Element* pEle)
{
m_listEle.push_back(pEle);
}
void DelElement(Element* pEle)
{
m_listEle.remove(pEle);
}
//访问者访问Computer时将依次访问各组件
void AcceptVisitor(Visitor* pVisitor)
{
for(Element* pElement: m_listEle)
{
pElement->AcceptVisitor(pVisitor);
}
}
private:
list<Element*> m_listEle;
};
//访问者实现类,实现各自的访问方法
class VisitorA : public Visitor
{
public:
void VisitCPU(Element* pEle)
{
printf("Visitor A record CPU's name:%s\n", pEle->GetName().c_str());
}
void VisitGPU(Element* pEle)
{
printf("Visitor A do nothing to GPU:%s\n", pEle->GetName().c_str());
}
void VisitDISK(Element* pEle)
{
printf("Visitor A change DISK:%s\n", pEle->GetName().c_str());
}
};
class VisitorB : public Visitor
{
public:
void VisitCPU(Element* pEle)
{
printf("Visitor B do nothing to CPU:%s\n", pEle->GetName().c_str());
}
void VisitGPU(Element* pEle)
{
printf("Visitor B record GPU's name:%s\n", pEle->GetName().c_str());
}
void VisitDISK(Element* pEle)
{
printf("Visitor B do nothing to DISK:%s\n", pEle->GetName().c_str());
}
};
//组件的实现类,调用访问者相应的访问方法
class CPU:public Element
{
public:
CPU(string strName):Element(strName){}
void AcceptVisitor(Visitor* pVisitor)
{
pVisitor->VisitCPU(this);
}
};
class GPU:public Element
{
public:
GPU(string strName):Element(strName){}
void AcceptVisitor(Visitor* pVisitor)
{
pVisitor->VisitGPU(this);
}
};
class Disk:public Element
{
public:
Disk(string strName):Element(strName){}
void AcceptVisitor(Visitor* pVisitor)
{
pVisitor->VisitDISK(this);
}
};
主函数中的使用
int main()
{
Computer oComputer;
oComputer.AddElement(new CPU("i9-10980XE"));
oComputer.AddElement(new GPU("Titan RTX"));
oComputer.AddElement(new Disk("HOF PRO M.2"));
VisitorA oVisitorA;
VisitorB oVisitorB;
oComputer.AcceptVisitor(&oVisitorA);
oComputer.AcceptVisitor(&oVisitorB);
return 0;
}
控制台输出结果
Visitor A record CPU's name:i9-10980XE
Visitor A do nothing to GPU:Titan RTX
Visitor A change DISK:HOF PRO M.2
Visitor B do nothing to CPU:i9-10980XE
Visitor B record GPU's name:Titan RTX
Visitor B do nothing to DISK:HOF PRO M.2
如有错误,欢迎指正