设计模式 - Visitor 模式(访问者模式)
作用:表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作.
UML结构图:
解析:
Visitor模式把对结点的访问封装成一个抽象基类,通过派生出不同的类生成新的访问方式.在实现的时候,在visitor抽象基类中声明了对所有不同结点进行访问的接口函数,如图中的VisitConcreateElementA函数等,这样也造成了Visitor模式的一个缺陷--新加入一个结点的时候都要添加Visitor中的对其进行访问接口函数,这样使得所有的Visitor及其派生类都要重新编译了,也就是说Visitor模式一个缺点就是添加新的结点十分困难.另外,还需要指出的是Visitor模式采用了所谓的"双重分派"的技术,拿上图来作为例子,要对某一个结点进行访问,首先需要产生一个Element的派生类对象,其次要传入一个Visitor类派生类对象来调用对应的Accept函数,也就是说,到底对哪种Element采用哪种Visitor访问,需要两次动态绑定才可以确定下来,具体的实现可以参考下面实现代码中的Main.cpp部分是如何调用这些类的.
代码实现:
Visitor.h
1
2 #ifndef VISITOR_H
3 #define VISITOR_H
4
5 class Visitor;
6
7 class Element
8 {
9 public:
10 virtual ~Element(){}
11
12 virtual void Accept(Visitor &rVisitor) = 0;
13
14 protected:
15 Element(){}
16 };
17
18 class ConcreateElementA
19 : public Element
20 {
21 public:
22 virtual ~ConcreateElementA() {}
23
24 virtual void Accept(Visitor &rVisitor);
25 };
26
27 class ConcreateElementB
28 : public Element
29 {
30 public:
31 virtual ~ConcreateElementB() {}
32
33 virtual void Accept(Visitor &rVisitor);
34 };
35
36 class Visitor
37 {
38 public:
39 virtual ~Visitor(){}
40
41 virtual void VisitConcreateElementA(ConcreateElementA *pConcreateElementA) = 0;
42 virtual void VisitConcreateElementB(ConcreateElementB *pConcreateElementB) = 0;
43
44 protected:
45 Visitor(){}
46 };
47
48 class ConcreateVisitorA
49 : public Visitor
50 {
51 public:
52 virtual ~ConcreateVisitorA(){}
53
54 virtual void VisitConcreateElementA(ConcreateElementA *pConcreateElementA);
55 virtual void VisitConcreateElementB(ConcreateElementB *pConcreateElementB);
56 };
57
58 class ConcreateVisitorB
59 : public Visitor
60 {
61 public:
62 virtual ~ConcreateVisitorB(){}
63
64 virtual void VisitConcreateElementA(ConcreateElementA *pConcreateElementA);
65 virtual void VisitConcreateElementB(ConcreateElementB *pConcreateElementB);
66 };
67
68 #endif
69
2 #ifndef VISITOR_H
3 #define VISITOR_H
4
5 class Visitor;
6
7 class Element
8 {
9 public:
10 virtual ~Element(){}
11
12 virtual void Accept(Visitor &rVisitor) = 0;
13
14 protected:
15 Element(){}
16 };
17
18 class ConcreateElementA
19 : public Element
20 {
21 public:
22 virtual ~ConcreateElementA() {}
23
24 virtual void Accept(Visitor &rVisitor);
25 };
26
27 class ConcreateElementB
28 : public Element
29 {
30 public:
31 virtual ~ConcreateElementB() {}
32
33 virtual void Accept(Visitor &rVisitor);
34 };
35
36 class Visitor
37 {
38 public:
39 virtual ~Visitor(){}
40
41 virtual void VisitConcreateElementA(ConcreateElementA *pConcreateElementA) = 0;
42 virtual void VisitConcreateElementB(ConcreateElementB *pConcreateElementB) = 0;
43
44 protected:
45 Visitor(){}
46 };
47
48 class ConcreateVisitorA
49 : public Visitor
50 {
51 public:
52 virtual ~ConcreateVisitorA(){}
53
54 virtual void VisitConcreateElementA(ConcreateElementA *pConcreateElementA);
55 virtual void VisitConcreateElementB(ConcreateElementB *pConcreateElementB);
56 };
57
58 class ConcreateVisitorB
59 : public Visitor
60 {
61 public:
62 virtual ~ConcreateVisitorB(){}
63
64 virtual void VisitConcreateElementA(ConcreateElementA *pConcreateElementA);
65 virtual void VisitConcreateElementB(ConcreateElementB *pConcreateElementB);
66 };
67
68 #endif
69
Visitor.cpp
1
2 #include "Visitor.h"
3 #include <iostream>
4
5 void ConcreateElementA::Accept(Visitor &rVisitor)
6 {
7 rVisitor.VisitConcreateElementA(this);
8 }
9
10 void ConcreateElementB::Accept(Visitor &rVisitor)
11 {
12 rVisitor.VisitConcreateElementB(this);
13 }
14
15 void ConcreateVisitorA::VisitConcreateElementA(ConcreateElementA *pConcreateElementA)
16 {
17 std::cout << "VisitConcreateElementA By ConcreateVisitorA\n";
18 }
19
20 void ConcreateVisitorA::VisitConcreateElementB(ConcreateElementB *pConcreateElementA)
21 {
22 std::cout << "VisitConcreateElementB By ConcreateVisitorA\n";
23 }
24
25 void ConcreateVisitorB::VisitConcreateElementA(ConcreateElementA *pConcreateElementA)
26 {
27 std::cout << "VisitConcreateElementA By ConcreateVisitorB\n";
28 }
29
30 void ConcreateVisitorB::VisitConcreateElementB(ConcreateElementB *pConcreateElementA)
31 {
32 std::cout << "VisitConcreateElementB By ConcreateVisitorB\n";
33 }
34
2 #include "Visitor.h"
3 #include <iostream>
4
5 void ConcreateElementA::Accept(Visitor &rVisitor)
6 {
7 rVisitor.VisitConcreateElementA(this);
8 }
9
10 void ConcreateElementB::Accept(Visitor &rVisitor)
11 {
12 rVisitor.VisitConcreateElementB(this);
13 }
14
15 void ConcreateVisitorA::VisitConcreateElementA(ConcreateElementA *pConcreateElementA)
16 {
17 std::cout << "VisitConcreateElementA By ConcreateVisitorA\n";
18 }
19
20 void ConcreateVisitorA::VisitConcreateElementB(ConcreateElementB *pConcreateElementA)
21 {
22 std::cout << "VisitConcreateElementB By ConcreateVisitorA\n";
23 }
24
25 void ConcreateVisitorB::VisitConcreateElementA(ConcreateElementA *pConcreateElementA)
26 {
27 std::cout << "VisitConcreateElementA By ConcreateVisitorB\n";
28 }
29
30 void ConcreateVisitorB::VisitConcreateElementB(ConcreateElementB *pConcreateElementA)
31 {
32 std::cout << "VisitConcreateElementB By ConcreateVisitorB\n";
33 }
34
Main.cpp
1
2 #include "Visitor.h"
3
4 int main()
5 {
6 Visitor *pVisitorA = new ConcreateVisitorA();
7 Element *pElement = new ConcreateElementA();
8
9 pElement->Accept(*pVisitorA);
10
11 delete pElement;
12 delete pVisitorA;
13
14 return 0;
15 }
16
2 #include "Visitor.h"
3
4 int main()
5 {
6 Visitor *pVisitorA = new ConcreateVisitorA();
7 Element *pElement = new ConcreateElementA();
8
9 pElement->Accept(*pVisitorA);
10
11 delete pElement;
12 delete pVisitorA;
13
14 return 0;
15 }
16