1.Visitor模式:将更新(变更)封装到一个类中(访问操作),并由待更改类提供一个接收接口,则可在不破坏类的前提下,为类提供增加新的新操作。
2.Visitor模式结构图

Visitor模式的关键是双分派(Double-Dispatch)的技术:Accept()操作是一个双分派的操作,具体调用哪个Accept()操作,有两个决定因素(1)Element类型(2)Visitor类型。
3.实现

1 #ifndef _VISITOR_H_
2 #define _VISITOR_H_
3
4 class Element;
5
6 class Visitor
7 {
8 public:
9 virtual ~Visitor();
10 virtual void VisitConcreteElementA(Element* elm) = 0;
11 virtual void VisitConcreteElementB(Element* elm) = 0;
12 protected:
13 Visitor();
14 private:
15 };
16
17 class ConcreteVisitorA:public Visitor
18 {
19 public:
20 ConcreteVisitorA();
21 virtual ~ConcreteVisitorA();
22 virtual void VisitConcreteElementA(Element* elm);
23 virtual void VisitConcreteElementB(Element* elm);
24 protected:
25 private:
26 };
27
28 class ConcreteVisitorB:public Visitor
29 {
30 public:
31 ConcreteVisitorB();
32 virtual ~ConcreteVisitorB();
33 virtual void VisitConcreteElementA(Element* elm);
34 virtual void VisitConcreteElementB(Element* elm);
35 protected:
36 private:
37 };
38
39 #endif

1 #include "Visitor.h"
2 #include "Element.h"
3 #include <iostream>
4 using namespace std;
5
6 Visitor::Visitor()
7 {
8
9 }
10 Visitor::~Visitor()
11 {
12
13 }
14 ConcreteVisitorA::ConcreteVisitorA()
15 {
16
17 }
18 ConcreteVisitorA::~ConcreteVisitorA()
19 {
20
21 }
22 void ConcreteVisitorA::VisitConcreteElementA(Element* elm)
23 {
24 cout<<"i will visit ConcreteElementA..."<<endl;
25 }
26 void ConcreteVisitorA::VisitConcreteElementB(Element* elm)
27 {
28 cout<<"i will visit ConcreteElementB..."<<endl;
29 }
30 ConcreteVisitorB::ConcreteVisitorB()
31 {
32
33 }
34 ConcreteVisitorB::~ConcreteVisitorB()
35 {
36
37 }
38 void ConcreteVisitorB::VisitConcreteElementA(Element* elm)
39 {
40 cout<<"i will visit ConcreteElementA..."<<endl;
41 }
42 void ConcreteVisitorB::VisitConcreteElementB(Element* elm)
43 {
44 cout<<"i will visit ConcreteElementB..."<<endl;
45 }

1 #ifndef _ELEMENT_H_
2 #define _ELEMENT_H_
3
4 class Visitor;
5
6 class Element
7 {
8 public:
9 virtual ~Element();
10 virtual void Accept(Visitor* vis) = 0;
11 protected:
12 Element();
13 private:
14 };
15
16 class ConcreteElementA:public Element
17 {
18 public:
19 ConcreteElementA();
20 ~ConcreteElementA();
21 void Accept(Visitor* vis);
22 protected:
23 private:
24 };
25
26 class ConcreteElementB:public Element
27 {
28 public:
29 ConcreteElementB();
30 ~ConcreteElementB();
31 void Accept(Visitor* vis);
32 protected:
33 private:
34 };
35
36 #endif

1 #include "Element.h"
2 #include "Visitor.h"
3 #include <iostream>
4
5 using namespace std;
6
7 Element::Element()
8 {
9
10 }
11 Element::~Element()
12 {
13
14 }
15 void Element::Accept(Visitor* vis)
16 {
17
18 }
19 ConcreteElementA::ConcreteElementA()
20 {
21
22 }
23 ConcreteElementA::~ConcreteElementA()
24 {
25
26 }
27 void ConcreteElementA::Accept(Visitor* vis)
28 {
29 vis->VisitConcreteElementA(this);
30 cout<<"visiting ConcreteElementA..."<<endl;
31 }
32 ConcreteElementB::ConcreteElementB()
33 {
34
35 }
36 ConcreteElementB::~ConcreteElementB()
37 {
38
39 }
40 void ConcreteElementB::Accept(Visitor* vis)
41 {
42 cout<<"visiting ConcreteElementB..."<<endl;
43 vis->VisitConcreteElementB(this);
44 }

1 #include "Element.h"
2 #include "Visitor.h"
3 #include <iostream>
4
5 using namespace std;
6
7 int main(int argc,char* argv[])
8 {
9 Visitor* vis = new ConcreteVisitorA();
10 Element* elm = new ConcreteElementA();
11 elm->Accept(vis);
12
13 return 0;
14 }
4.Visitor模式的缺点
(1)破坏了封装性
(2)ConcreteElement的扩展很困难:每增加一个Element的子类,就要修改Visitor的接口,使得可以提供给这个新增加的子类的访问机制。
来源:https://www.cnblogs.com/programmer-wfq/p/4671316.html
