码迷,mamicode.com
首页 > 其他好文 > 详细

Visitor Pattern

时间:2015-07-23 19:19:19      阅读:103      评论:0      收藏:0      [点我收藏+]

标签:

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
Visitor.h
技术分享
 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 }
Visitor.cpp
技术分享
 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
Element.h
技术分享
 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 }
Element.cpp
技术分享
 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 }
main.cpp

4.Visitor模式的缺点

(1)破坏了封装性

(2)ConcreteElement的扩展很困难:每增加一个Element的子类,就要修改Visitor的接口,使得可以提供给这个新增加的子类的访问机制。

Visitor Pattern

标签:

原文地址:http://www.cnblogs.com/programmer-wfq/p/4671316.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!