• 访问者模式 行为型设计模式之九


    1.定义

            在不改变数据结构的前提下,增加作用于一组对象元素的新功能。

    2.动机

    1. 访问者模式适用于数据结构相对稳定的系统
    2. 它把数据结构和作用于数据结构之上的操作之间的耦合解脱开,使得操作集合可以相对自由的演化。
    3. 访问者模式的目的是要把处理从数据结构分离出来。如果这样的系统有比较稳定的数据结构,又有已与变化的算法的话,使用访问者模式就是比较合适的,因为访问者模式使得算法操作的增加变得更容易。反之亦然。

            一句话总结就是,访问者不会改变原有系统的数据结构,而只是使用原有系统的数据去实现自己的功能。这个实现的功能可以自己定制,但是原有系统需要留出这样的访问者应用接口。

    3.示例代码

            一台电脑中有很多组件,CPU、GPU、硬盘。维修人员对电脑进行整体维修时,需要对各部件依次进行维修,而且每部件具体的维修方式不同。不同的维修人员对相同的部件维修方式可能也不同。维修人员就是访问者。访问者类中实现了针对不同部件的维修方式。电脑就是被访问者。被访问者提供访问接口,使用访问者类中实现的不同部件维修方式,对内部部件进行访问。

    1. #include
    2. #include
    3. using namespace std;
    4. class Visitor;
    5. //组成Computer的各组件基类
    6. class Element
    7. {
    8. public:
    9. Element(string strName) :m_strName(strName) {}
    10. string GetName()
    11. {
    12. return m_strName;
    13. }
    14. //组件接受访问者访问的接口
    15. virtual void AcceptVisitor(Visitor* pVisitor) = 0;
    16. private:
    17. //组件的标识名称
    18. string m_strName;
    19. };
    20. //访问者基类,针对不同组件,提供不同的访问接口
    21. class Visitor
    22. {
    23. public:
    24. virtual void VisitCPU(Element* pEle) = 0;
    25. virtual void VisitGPU(Element* pEle) = 0;
    26. virtual void VisitDISK(Element* pEle) = 0;
    27. };
    28. //Computer类,由各组件组成,访问者访问Computer时将依次访问各组件
    29. class Computer
    30. {
    31. public:
    32. ~Computer()
    33. {
    34. for (Element* pElement : m_listEle)
    35. {
    36. delete pElement;
    37. }
    38. }
    39. void AddElement(Element* pEle)
    40. {
    41. m_listEle.push_back(pEle);
    42. }
    43. void DelElement(Element* pEle)
    44. {
    45. m_listEle.remove(pEle);
    46. }
    47. //访问者访问Computer时将依次访问各组件
    48. void AcceptVisitor(Visitor* pVisitor)
    49. {
    50. for (Element* pElement : m_listEle)
    51. {
    52. pElement->AcceptVisitor(pVisitor);
    53. }
    54. }
    55. private:
    56. list m_listEle;
    57. };
    58. //访问者实现类,实现各自的访问方法
    59. class VisitorA : public Visitor
    60. {
    61. public:
    62. void VisitCPU(Element* pEle)
    63. {
    64. printf("Visitor A record CPU's name:%s\n", pEle->GetName().c_str());
    65. }
    66. void VisitGPU(Element* pEle)
    67. {
    68. printf("Visitor A do nothing to GPU:%s\n", pEle->GetName().c_str());
    69. }
    70. void VisitDISK(Element* pEle)
    71. {
    72. printf("Visitor A change DISK:%s\n", pEle->GetName().c_str());
    73. }
    74. };
    75. class VisitorB : public Visitor
    76. {
    77. public:
    78. void VisitCPU(Element* pEle)
    79. {
    80. printf("Visitor B do nothing to CPU:%s\n", pEle->GetName().c_str());
    81. }
    82. void VisitGPU(Element* pEle)
    83. {
    84. printf("Visitor B record GPU's name:%s\n", pEle->GetName().c_str());
    85. }
    86. void VisitDISK(Element* pEle)
    87. {
    88. printf("Visitor B do nothing to DISK:%s\n", pEle->GetName().c_str());
    89. }
    90. };
    91. //组件的实现类,调用访问者相应的访问方法
    92. class CPU :public Element
    93. {
    94. public:
    95. CPU(string strName) :Element(strName) {}
    96. void AcceptVisitor(Visitor* pVisitor)
    97. {
    98. pVisitor->VisitCPU(this);
    99. }
    100. };
    101. class GPU :public Element
    102. {
    103. public:
    104. GPU(string strName) :Element(strName) {}
    105. void AcceptVisitor(Visitor* pVisitor)
    106. {
    107. pVisitor->VisitGPU(this);
    108. }
    109. };
    110. class Disk :public Element
    111. {
    112. public:
    113. Disk(string strName) :Element(strName) {}
    114. void AcceptVisitor(Visitor* pVisitor)
    115. {
    116. pVisitor->VisitDISK(this);
    117. }
    118. };
    119. int main()
    120. {
    121. Computer oComputer;
    122. oComputer.AddElement(new CPU("i9-10980XE"));
    123. oComputer.AddElement(new GPU("Titan RTX"));
    124. oComputer.AddElement(new Disk("HOF PRO M.2"));
    125. VisitorA oVisitorA;
    126. VisitorB oVisitorB;
    127. oComputer.AcceptVisitor(&oVisitorA);
    128. oComputer.AcceptVisitor(&oVisitorB);
    129. return 0;
    130. }

    4.组成结构

    1. Visitor 是抽象访问者,为该对象结构中的 ConcreteElement 的每一个类声明一个 visit 操作
    2. ConcreteVisitor :是一个具体的访问值 实现每个有 Visitor 声明的操作,是每个操作实现的部分.
    3. ObjectStructure :能枚举它的元素, 可以提供一个高层的接口,用来允许访问者访问元素
    4. Element: 定义一个 accept  方法,接收一个访问者对象
    5. ConcreteElement: 为具体元素,实现了 accept  方法

    5.引用

    C++设计模式——访问者模式 - 冰糖葫芦很乖 - 博客园 (cnblogs.com)

     

  • 相关阅读:
    分享一款基于 AI 的 Chrome 插件
    Windows上部署Discuz论坛
    关于IvorySQL和OpenGauss包SPEC处理的一些思考
    ArcGIS10.1软件安装教程
    vscode c++ 报错identifier “string“ is undefined
    细说Hash(哈希)
    Halcon WPF 开发学习笔记(3):WPF+Halcon初步开发
    VS 配置 OpenCV (亲测可用)
    C++(17):模板嵌套类的.template及::template
    运行业务项目时,如何管理客户关系?
  • 原文地址:https://blog.csdn.net/Physics_ITBoy/article/details/133638460