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 }
输出结果: