服务器之家

服务器之家 > 正文

C++实现访问者模式的基础介绍

时间:2022-01-10 14:58     来源/作者:herryone123

一、访问者模式基础知识

1.1 模式动机

       对于系统中的某些对象中可能存在多种不同类型的元素,而且不同的调用者使用这些元素时也有所区别,这些调用者称为访问者。

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

访问者模式的应用场景:

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

1.2 访问者模式结构

C++实现访问者模式的基础介绍

 访问者模式中对象结构存储了不同类型的元素对象,以提供不同访问者访问。访问者模式包括两个层次结构,一个是访问者层次结构,提供了抽象访问者和具体访问者,一个是元素层次结构,提供了抽象元素和具体元素。

相同的访问者可以以不同的方式访问不同的元素,相同的元素可以接受不同访问者以不同的方式访问。

(1)Visitor (抽象访问者)

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

(2)ConcreteVisitor (具体访问者)

具体访问者实现了每个由抽象访问者声明的操作,每一个操作用于访问对象结构中一种元素类型的元素。

(3)Element(抽象元素)

抽象元素一般是抽象类或接口,定义一个accept()方法,该方法以一个抽象访问者作为参数。

(4)ConcreteElement (具体元素)

具体访问者实现了accept()方法,在其accept()

(5)ObjectStructure(对象结构)

对象结构是一个元素的集合,它用于存放元素对象,并且提供了遍历其内部元素的方法。

1.3 访问者模式优缺点

访问者模式优点:

  • 访问者模式的优点就是增加新的操作很容易,因为增加新的操作就意味着增加一个新的访问者。访问者模式将有关的行为集中到一个访问者对象中。

模式的缺点:

  • 使增加新的元素类变得困难。在访问者模式中,每增加一个新的元素都意味着要在抽象访问者角色中增加一个新的抽象操作,并在每一个具体访问者中增加相应的具体操作,违背“开闭原则”的要求。

1.4 访问者模式应用

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <iostream>
 
#include <vector>
 
using namespace std;
 
class ConcreteElementA;
class ConcreteElementB;
 
/*抽象访问者  声明了访问元素对象的方法,通常为每一种类型的元素对象都提供一个访问方法*/
class Visitor
 
{
 
public:
 
     virtual void VisitConcreteElementA(ConcreteElementA *pElementA) = 0;
     virtual void VisitConcreteElementB(ConcreteElementB *pElementB) = 0;
 
};
 
/*具体访问者 用于定义对不同类型元素对象的操作*/
class ConcreteVisitor1 : public Visitor
 
{
public:
     void VisitConcreteElementA(ConcreteElementA *pElementA){
        // 现在根据传进来的pElementA,可以对ConcreteElementA中的element进行操作
    }
 
     void VisitConcreteElementB(ConcreteElementB *pElementB){
         // 现在根据传进来的pElementB,可以对ConcreteElementB中的element进行操作
    }
 
};
 
/*具体访问者2*/
class ConcreteVisitor2 : public Visitor
{
 
public:
     void VisitConcreteElementA(ConcreteElementA *pElementA){
    }
     void VisitConcreteElementB(ConcreteElementB *pElementB){
    }
};
 
 
/*抽象元素类 声明accept()方法,用于接受访问者的访问*/
class Element
 
{
public:
     virtual void Accept(Visitor *pVisitor) = 0;//accept用于接受访问者的访问
};
 
/*具体元素类 通过调用Visitor类的visit()方法实现对元素的访问*/
class ConcreteElementA : public Element
{
public:
     void Accept(Visitor *pVisitor)//通过调用visitor对象的 visit()方法实现对元素对象的访问
    {
        pVisitor->VisitConcreteElementA(this);
    }
};
 
/*具体元素类 */
class ConcreteElementB : public Element
{
public:
     void Accept(Visitor *pVisitor)
    {
     pVisitor->VisitConcreteElementB(this);
    }
};
 
// ObjectStructure类(对象结构类),能枚举它的元素,可以提供一个高层的接口以允许访问者访问它的元素
class ObjectStructure
{
public:
     void Attach(Element *pElement){
         elements.push_back(pElement);
    }
 
     void Detach(Element *pElement)  
    {
 
         vector<Element *>::iterator it = find(elements.begin(), elements.end(), pElement);
         if (it != elements.end())
         {
              elements.erase(it);
         }
    }
 
     void Accept(Visitor *pVisitor){
     // 为每一个element设置visitor,进行对应的操作
         for (vector<Element *>::const_iterator it = elements.begin(); it != elements.end(); ++it)
         {
              (*it)->Accept(pVisitor);
         }
 
}
 
int main()
{
     //实例化对象结构,用于存放元素对象,提供遍历其内部元素的方法
     ObjectStructure *pObject = new ObjectStructure;
      //实例化具体元素 并将创建好的元素放入对象结构中
     ConcreteElementA *pElementA = new ConcreteElementA;
     ConcreteElementB *pElementB = new ConcreteElementB;
     pObject->Attach(pElementA);
     pObject->Attach(pElementB);
     //实例化访问者                                                                                                                     
     ConcreteVisitor1 *pVisitor1 = new ConcreteVisitor1;
     ConcreteVisitor2 *pVisitor2 = new ConcreteVisitor2;
     //调用accept方法 来接受访问者对象的访问
     pObject->Accept(pVisitor1);
     pObject->Accept(pVisitor2);
 
     if (pVisitor2) delete pVisitor2;
     if (pVisitor1) delete pVisitor1;
     if (pElementB) delete pElementB;
     if (pElementA) delete pElementA;
     if (pObject) delete pObject;
 
     return 0;
}

参考文献:

【1】访问者模式(c++实现):访问者模式(c++实现)

【2】C++设计模式之访问者模式: http://www.zzvips.com/article/138802.html

到此这篇关于C++实现访问者模式的文章就介绍到这了,更多相关C++访问者模式内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/kenjianqi1647/article/details/119632572

标签:

相关文章

热门资讯

蜘蛛侠3英雄无归3正片免费播放 蜘蛛侠3在线观看免费高清完整
蜘蛛侠3英雄无归3正片免费播放 蜘蛛侠3在线观看免费高清完整 2021-08-24
yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
2021年耽改剧名单 2021要播出的59部耽改剧列表
2021年耽改剧名单 2021要播出的59部耽改剧列表 2021-03-05
返回顶部