织梦CMS - 轻松建站从此开始!

罗索

设计模式 - Visitor 模式(访问者模式)

jackyhwei 发布于 2011-06-12 22:08 点击:次 
表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作.
TAG:

作用:表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作.

UML结构图:

解析:
Visitor模式把对结点的访问封装成一个抽象基类,通过派生出不同的类生成新的访问方式.在实现的时候,在visitor抽象基类中声明了对所有不同结点进行访问的接口函数,如图中的VisitConcreateElementA函数等,这样也造成了Visitor模式的一个缺陷--新加入一个结点的时候都要添加Visitor中的对其进行访问接口函数,这样使得所有的Visitor及其派生类都要重新编译了,也就是说Visitor模式一个缺点就是添加新的结点十分困难.另外,还需要指出的是Visitor模式采用了所谓的"双重分派"的技术,拿上图来作为例子,要对某一个结点进行访问,首先需要产生一个Element的派生类对象,其次要传入一个Visitor类派生类对象来调用对应的Accept函数,也就是说,到底对哪种Element采用哪种Visitor访问,需要两次动态绑定才可以确定下来,具体的实现可以参考下面实现代码中的Main.cpp部分是如何调用这些类的.

代码实现:

Visitor.h

  1. #ifndef VISITOR_H 
  2. #define VISITOR_H 
  3.  
  4. class Visitor; 
  5.  
  6. class Element 
  7. public
  8.     virtual ~Element(){} 
  9.     virtual void Accept(Visitor &rVisitor) = 0; 
  10. protected
  11.     Element(){} 
  12. }; 
  13.  
  14. class ConcreateElementA : public Element 
  15. public
  16.     virtual ~ConcreateElementA() {} 
  17.     virtual void Accept(Visitor &rVisitor); 
  18. }; 
  19.  
  20. class ConcreateElementB : public Element 
  21. public
  22.     virtual ~ConcreateElementB() {} 
  23.     virtual void Accept(Visitor &rVisitor); 
  24. }; 
  25.  
  26. class Visitor 
  27. public
  28.     virtual ~Visitor(){} 
  29.  
  30.     virtual void VisitConcreateElementA(ConcreateElementA *pConcreateElementA) = 0; 
  31.     virtual void VisitConcreateElementB(ConcreateElementB *pConcreateElementB) = 0; 
  32.  
  33. protected
  34.     Visitor(){} 
  35. }; 
  36.  
  37. class ConcreateVisitorA : public Visitor 
  38. public
  39.     virtual ~ConcreateVisitorA(){} 
  40.  
  41.     virtual void VisitConcreateElementA(ConcreateElementA *pConcreateElementA); 
  42.     virtual void VisitConcreateElementB(ConcreateElementB *pConcreateElementB); 
  43. }; 
  44.  
  45. class ConcreateVisitorB : public Visitor 
  46. public
  47.     virtual ~ConcreateVisitorB(){} 
  48.  
  49.     virtual void VisitConcreateElementA(ConcreateElementA *pConcreateElementA); 
  50.     virtual void VisitConcreateElementB(ConcreateElementB *pConcreateElementB); 
  51. }; 
  52.  
  53. #endif 

Visitor.cpp

  1. #include "Visitor.h" 
  2. #include <iostream> 
  3.  
  4. void ConcreateElementA::Accept(Visitor &rVisitor) 
  5.     rVisitor.VisitConcreateElementA(this); 
  6.  
  7. void ConcreateElementB::Accept(Visitor &rVisitor) 
  8.     rVisitor.VisitConcreateElementB(this); 
  9.  
  10. void ConcreateVisitorA::VisitConcreateElementA(ConcreateElementA *pConcreateElementA) 
  11.     std::cout << "VisitConcreateElementA By ConcreateVisitorA\n"
  12.  
  13. void ConcreateVisitorA::VisitConcreateElementB(ConcreateElementB *pConcreateElementA) 
  14.     std::cout << "VisitConcreateElementB By ConcreateVisitorA\n"
  15.  
  16. void ConcreateVisitorB::VisitConcreateElementA(ConcreateElementA *pConcreateElementA) 
  17.     std::cout << "VisitConcreateElementA By ConcreateVisitorB\n"
  18.  
  19. void ConcreateVisitorB::VisitConcreateElementB(ConcreateElementB *pConcreateElementA) 
  20.     std::cout << "VisitConcreateElementB By ConcreateVisitorB\n"

main.cpp

  1. #include "Visitor.h" 
  2.  
  3. int main() 
  4.     Visitor *pVisitorA = new ConcreateVisitorA(); 
  5.     Element *pElement  = new ConcreateElementA(); 
  6.  
  7.     pElement->Accept(*pVisitorA); 
  8.  
  9.     delete pElement; 
  10.     delete pVisitorA; 
  11.  
  12.     return 0; 

 

(whiteyun)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201106/14550.html]
本文出处:cnblogs.com/whiteyun 作者:whiteyun
顶一下
(1)
100%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容