在不改变数据结构的前提下,增加作用于一组对象元素的新功能。
一句话总结就是,访问者不会改变原有系统的数据结构,而只是使用原有系统的数据去实现自己的功能。这个实现的功能可以自己定制,但是原有系统需要留出这样的访问者应用接口。
一台电脑中有很多组件,CPU、GPU、硬盘。维修人员对电脑进行整体维修时,需要对各部件依次进行维修,而且每部件具体的维修方式不同。不同的维修人员对相同的部件维修方式可能也不同。维修人员就是访问者。访问者类中实现了针对不同部件的维修方式。电脑就是被访问者。被访问者提供访问接口,使用访问者类中实现的不同部件维修方式,对内部部件进行访问。
- #include
- #include
- 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
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;
- }
C++设计模式——访问者模式 - 冰糖葫芦很乖 - 博客园 (cnblogs.com)