阅读量:1
访问者模式
C++
#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; }
C
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct Element Element; typedef struct Visitor Visitor; typedef struct Computer Computer; typedef struct CPU CPU; typedef struct GPU GPU; typedef struct Disk Disk; // 组件基类 struct Element { char *m_strName; void (*accept)(struct Element *, struct Visitor *); }; // 访问者基类 struct Visitor { void (*visitCPU)(struct Element *); void (*visitGPU)(struct Element *); void (*visitDisk)(struct Element *); }; // Computer类 struct Computer { struct Element **m_listEle; size_t m_listSize; size_t m_listCapacity; }; // CPU类 struct CPU { struct Element base; }; // GPU类 struct GPU { struct Element base; }; // Disk类 struct Disk { struct Element base; }; // 创建组件 struct Element *createElement(const char *name, void (*accept)(struct Element *, struct Visitor *)) { struct Element *element = malloc(sizeof(struct Element)); element->m_strName = strdup(name); element->accept = accept; return element; } // 创建访问者 struct Visitor *createVisitor(void (*visitCPU)(struct Element *), void (*visitGPU)(struct Element *), void (*visitDisk)(struct Element *)) { struct Visitor *visitor = malloc(sizeof(struct Visitor)); visitor->visitCPU = visitCPU; visitor->visitGPU = visitGPU; visitor->visitDisk = visitDisk; return visitor; } // 创建Computer struct Computer *createComputer() { struct Computer *computer = malloc(sizeof(struct Computer)); computer->m_listEle = NULL; computer->m_listSize = 0; computer->m_listCapacity = 0; return computer; } // 添加组件到Computer void addElement(struct Computer *computer, struct Element *element) { if (computer->m_listSize >= computer->m_listCapacity) { size_t newCapacity = computer->m_listCapacity == 0 ? 1 : computer->m_listCapacity * 2; computer->m_listEle = realloc(computer->m_listEle, newCapacity * sizeof(struct Element *)); computer->m_listCapacity = newCapacity; } computer->m_listEle[computer->m_listSize++] = element; } // 删除组件 void delElement(struct Computer *computer, struct Element *element) { size_t i; for (i = 0; i < computer->m_listSize; i++) { if (computer->m_listEle[i] == element) { memmove(&computer->m_listEle[i], &computer->m_listEle[i + 1], (computer->m_listSize - i - 1) * sizeof(struct Element *)); computer->m_listEle[--computer->m_listSize] = NULL; break; } } } // 访问者访问Computer void acceptVisitor(struct Computer *computer, struct Visitor *visitor) { size_t i; for (i = 0; i < computer->m_listSize; i++) { computer->m_listEle[i]->accept(computer->m_listEle[i], visitor); } } // 清理Computer void clearComputer(struct Computer *computer) { size_t i; for (i = 0; i < computer->m_listSize; i++) { free(computer->m_listEle[i]->m_strName); free(computer->m_listEle[i]); } free(computer->m_listEle); free(computer); } // 访问者A实现 void visitorAVisitCPU(struct Element *ele) { printf("Visitor A record CPU's name:%s\n", ele->m_strName); } void visitorAVisitGPU(struct Element *ele) { printf("Visitor A do nothing to GPU:%s\n", ele->m_strName); } void visitorAVisitDisk(struct Element *ele) { printf("Visitor A change DISK:%s\n", ele->m_strName); } // 访问者B实现 void visitorBVisitCPU(struct Element *ele) { printf("Visitor B do nothing to CPU:%s\n", ele->m_strName); } void visitorBVisitGPU(struct Element *ele) { printf("Visitor B record GPU's name:%s\n", ele->m_strName); } void visitorBVisitDisk(struct Element *ele) { printf("Visitor B do nothing to DISK:%s\n", ele->m_strName); } int main() { struct Computer *oComputer = createComputer(); addElement(oComputer, createElement("i9-10980XE", visitorAVisitCPU)); addElement(oComputer, createElement("Titan RTX", visitorAVisitGPU)); addElement(oComputer, createElement("HOF PRO M.2", visitorAVisitDisk)); struct Visitor *oVisitorA = createVisitor(visitorAVisitCPU, visitorAVisitGPU, visitorAVisitDisk); struct Visitor *oVisitorB = createVisitor(visitorBVisitCPU, visitorBVisitGPU, visitorBVisitDisk); acceptVisitor(oComputer, oVisitorA); acceptVisitor(oComputer, oVisitorB); clearComputer(oComputer); free(oVisitorA); free(oVisitorB); return 0; }