024 --- 第28章 访问者模式

简述:

  访问者模式:表示一个作用于某对象结构中各个元素的操作,它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

  访问者模式包括:抽象访问者类、具体访问者类、对象枚举结构类、抽象元素类、具体元素类。

    抽象访问者类:为该对象结构中的每个具体元素类对象声明一个Visit操作。

    具体访问者类:实现每个由抽象访问者类声明的操作,每个操作实现算法的一部分,而该算法片段乃是对应于结构中对象的类。

    对象枚举结构类:能枚举它的元素,可以提供一个高层的接口以允许访问者访问它的元素。

    抽象元素类:定义一个Accept操作,它以一个访问者为参数。

    具体元素类:实现Accept操作。

 

应用场景:对象枚举类包含元素类列表,可以为元素类对象添加访问者类对象进行访问。使用在数据结构相对稳定的系统中,把算法和数据结构分离

 

注:开发环境调整为VS2017,操作系统win11

访问者模式:

  1 #include <iostream>
  2 #include <list>
  3 using namespace std;
  4 
  5 class CVisitor;
  6 // 抽象元素类
  7 class CElement
  8 {
  9 public:
 10     virtual void Accept(CVisitor* pVisitor) = 0;
 11 };
 12 
 13 // 抽象访问者类
 14 class CVisitor
 15 {
 16 public:
 17     virtual void VisitConcreteElementA(CElement* pConcreteElementA) = 0;
 18     virtual void VisitConcreteElementB(CElement* pConcreteElementB) = 0;
 19 };
 20 
 21 // 具体元素类
 22 class CConcreteElementA : public CElement
 23 {
 24     virtual void Accept(CVisitor* pVisitor) { pVisitor->VisitConcreteElementA(this); }
 25 
 26     void OperationA() {}
 27 };
 28 
 29 // 具体元素类
 30 class CConcreteElementB : public CElement
 31 {
 32     virtual void Accept(CVisitor* pVisitor) { pVisitor->VisitConcreteElementB(this); }
 33 
 34     void OperationB() {}
 35 };
 36 
 37 // 具体访问者类
 38 class CConcreteVisitor1 : public CVisitor
 39 {
 40 public:
 41     virtual void VisitConcreteElementA(CElement* pConcreteElementA)
 42     {
 43         cout << "CConcreteElementA 被 CConcreteVisitor1 访问" << endl;
 44     }
 45     virtual void VisitConcreteElementB(CElement* pConcreteElementB)
 46     {
 47         cout << "CConcreteElementB 被 CConcreteVisitor1 访问" << endl;
 48     }
 49 };
 50 
 51 // 具体访问者类
 52 class CConcreteVisitor2 : public CVisitor
 53 {
 54 public:
 55     virtual void VisitConcreteElementA(CElement* pConcreteElementA)
 56     {
 57         cout << "CConcreteElementA 被 CConcreteVisitor2 访问" << endl;
 58     }
 59     virtual void VisitConcreteElementB(CElement* pConcreteElementB)
 60     {
 61         cout << "CConcreteElementB 被 CConcreteVisitor2 访问" << endl;
 62     }
 63 };
 64 
 65 // 对象枚举结构类
 66 class CObjectStructure
 67 {
 68 private:
 69     list<CElement*> m_listElements;
 70 
 71 public:
 72     void Attach(CElement* pElement) { m_listElements.push_back(pElement); }
 73 
 74     void Detach(CElement* pElement) { m_listElements.remove(pElement); }
 75 
 76     void Accpet(CVisitor* pVisitor)
 77     {
 78         for (auto element : m_listElements)
 79             element->Accept(pVisitor);
 80     }
 81 };
 82 
 83 int main()
 84 {
 85     CObjectStructure obj;
 86 
 87     CConcreteElementA a;
 88     obj.Attach(&a);
 89 
 90     CConcreteElementB b;
 91     obj.Attach(&b);
 92 
 93     CConcreteVisitor1 v1;
 94     CConcreteVisitor2 v2;
 95 
 96     obj.Accpet(&v1);
 97     obj.Accpet(&v2);
 98 
 99     system("pause");
100     return 0;
101 }

 

输出结果:

 

 

 

例:男人女人成功失败

代码如下:

  1 #include <iostream>
  2 #include <list>
  3 using namespace std;
  4 
  5 class CAction;
  6 // 人类(抽象元素类)
  7 class CPerson
  8 {
  9 public:
 10     // 接受
 11     virtual void Accept(CAction* pAction) = 0;
 12 };
 13 
 14 // 状态抽象类(抽象访问者类)
 15 class CAction
 16 {
 17 public:
 18     virtual void GetManConclusion(CPerson* pMan) = 0;
 19     virtual void GetWomanConclusion(CPerson* pWoman) = 0;
 20 };
 21 
 22 // 男人类(具体元素类)
 23 class CMan : public CPerson
 24 {
 25 public:
 26     virtual void Accept(CAction* pAction) { pAction->GetManConclusion(this); }
 27 };
 28 
 29 // 女人类(具体元素类)
 30 class CWoman : public CPerson
 31 {
 32 public:
 33     virtual void Accept(CAction* pAction) { pAction->GetWomanConclusion(this); }
 34 };
 35 
 36 // 成功类(具体访问者类)
 37 class CSuccess : public CAction
 38 {
 39 public:
 40     virtual void GetManConclusion(CPerson* pMan)
 41     {
 42         cout << "男人成功时,背后多半有一个伟大的女人。" << endl;
 43     }
 44     virtual void GetWomanConclusion(CPerson* pWoman)
 45     {
 46         cout << "女人成功时,背后大多有一个不成功的男人。" << endl;
 47     }
 48 };
 49 
 50 // 失败类(具体访问者类)
 51 class CFailing : public CAction
 52 {
 53 public:
 54     virtual void GetManConclusion(CPerson* pMan)
 55     {
 56         cout << "男人失败时,闷头喝酒,谁也不用劝。" << endl;
 57     }
 58     virtual void GetWomanConclusion(CPerson* pWoman)
 59     {
 60         cout << "女人失败时,眼泪汪汪,谁也劝不了。" << endl;
 61     }
 62 };
 63 
 64 // 恋爱类(具体访问者类)
 65 class CAmativeness : public CAction
 66 {
 67 public:
 68     virtual void GetManConclusion(CPerson* pMan)
 69     {
 70         cout << "男人恋爱时,凡事不懂也要装懂。" << endl;
 71     }
 72     virtual void GetWomanConclusion(CPerson* pWoman)
 73     {
 74         cout << "女人恋爱时,遇事懂也装作不懂。" << endl;
 75     }
 76 };
 77 
 78 // 结婚类(具体访问者类)
 79 class CMarriage : public CAction
 80 {
 81 public:
 82     virtual void GetManConclusion(CPerson* pMan)
 83     {
 84         cout << "男人结婚时,感慨到:恋爱游戏终结时,‘有妻徒刑’遥无期。" << endl;
 85     }
 86     virtual void GetWomanConclusion(CPerson* pWoman)
 87     {
 88         cout << "女人结婚时,欣慰到:爱情长跑路漫漫,婚姻保险保平安。" << endl;
 89     }
 90 };
 91 
 92 // 对象结构类
 93 class CObjectStructure
 94 {
 95 private:
 96     list<CPerson*> m_listPerson;
 97 
 98 public:
 99     // 增加
100     void Attach(CPerson* pPerson) { m_listPerson.push_back(pPerson); }
101 
102     // 移除
103     void Detach(CPerson* pPerson) { m_listPerson.remove(pPerson); }
104 
105     // 查看显示
106     void Display(CAction* pAction)
107     {
108         for (auto person : m_listPerson)
109             person->Accept(pAction);
110     }
111 };
112 
113 int main()
114 {
115     CObjectStructure obj;
116     CMan man;
117     obj.Attach(&man);
118     CWoman woman;
119     obj.Attach(&woman);
120 
121     // 成功时的反应
122     CSuccess success;
123     obj.Display(&success);
124 
125     // 失败时的反应
126     CFailing failing;
127     obj.Display(&failing);
128 
129     // 恋爱时的反应
130     CAmativeness amtiveness;
131     obj.Display(&amtiveness);
132 
133     // 结婚时的反应
134     CMarriage marriage;
135     obj.Display(&marriage);
136 
137     system("pause");
138     return 0;
139 }

 

输出结果:

 

posted @ 2020-09-11 10:55  二是一种不三不亖的范  阅读(129)  评论(0编辑  收藏  举报