首页 > 编程语言 > 详细

C++设计模式实现--访问者(Visitor)模式

时间:2014-07-06 10:57:39      阅读:453      评论:0      收藏:0      [点我收藏+]

一. 访问者模式

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

结构如下:

bubuko.com,布布扣

二. 举例

假设有一项科学实验,是用来对比两种种子在不同环境下的生长情况。

两种种子,一种是普通的种子(Seed_A),一种是太空运回的种子(Seed_B)。

生长环境,分别是在多雨环境下(Rain_Status),阳光环境下(Sun_Status)等等。

结构如下:

bubuko.com,布布扣

代码如下:

  1. //状态  
  2. class Status  
  3. {  
  4. public:  
  5.     virtual ~Status() {}  
  6.       
  7.     virtual void VisitSeed_A(Seed* elm) {}  
  8.   
  9.     virtual void VisitSeed_B(Seed* elm) {}  
  10.   
  11. protected:  
  12.     Status() {}  
  13. };   
  14.   
  15. //下雨状态  
  16. class Rain_Status:public Status  
  17. {  
  18. public:  
  19.     Rain_Status() {}  
  20.       
  21.     virtual ~Rain_Status() {}  
  22.       
  23.     //下雨状态下A种子生长的情况  
  24.     virtual void VisitSeed_A(Seed* elm)  
  25.     {  
  26.         cout<<"Rain will visit Seed A..."<<endl;  
  27.     }  
  28.       
  29.     //下雨状态下B种子生长的情况  
  30.     virtual void VisitSeed_B(Seed* elm)  
  31.     {  
  32.         cout<<"Rain will visit Seed B..."<<endl;  
  33.     }  
  34. };   
  35.   
  36. //阳光状态  
  37. class Sun_Status:public Status  
  38. {  
  39. public:  
  40.     Sun_Status() {}  
  41.       
  42.     virtual ~Sun_Status() {}  
  43.       
  44.     //阳光状态下A种子生长的情况  
  45.     virtual void VisitSeed_A(Seed* elm)  
  46.     {  
  47.         cout<<"Sun will visit Seed A..."<<endl;  
  48.     }  
  49.       
  50.     //阳光状态下B种子生长的情况  
  51.     virtual void VisitSeed_B(Seed* elm)  
  52.     {  
  53.         cout<<"Sun will visit Seed B..."<<endl;  
  54.     }  
  55. };  
  56.   
  57.   
  58.   
  59. //种子  
  60. class Seed  
  61. {  
  62. public:  
  63.     virtual ~Seed() {}  
  64.     virtual void Accept(Status* vis) = 0;  
  65.   
  66. protected:  
  67.     Seed() {}  
  68. };  
  69.   
  70. //种子A,假设为普通种子  
  71. class Seed_A:public Seed  
  72. {  
  73. public:  
  74.     Seed_A() {}  
  75.       
  76.     ~Seed_A() {}  
  77.       
  78.     void Accept(Status* vis)  
  79.     {  
  80.         vis->VisitSeed_A(this);  
  81.     }  
  82. };   
  83.   
  84. //种子B,假设为从太空带回来的种子  
  85. class Seed_B:public Seed  
  86. {  
  87. public:  
  88.     Seed_B() {}  
  89.     ~Seed_B() {}  
  90.       
  91.     void Accept(Status* vis)  
  92.     {  
  93.         vis->VisitSeed_B(this);  
  94.     }  
  95. };  
  96.   
  97.   
  98. //对象结构类,为了对比不同种子  
  99. class ObjectStructure  
  100. {  
  101. private:  
  102.     list<Seed*> lseed;  
  103.   
  104. public:  
  105.     //Add  
  106.     void Attach(Seed* seed)  
  107.     {  
  108.         lseed.push_back(seed);  
  109.     }  
  110.   
  111.     //Delete  
  112.     void Detach(Seed* seed)  
  113.     {  
  114.         lseed.remove(seed);  
  115.     }  
  116.   
  117.     //Show  
  118.     void Display(Status* status)  
  119.     {  
  120.         list<Seed*>::iterator it = lseed.begin();  
  121.           
  122.         for (it; it != lseed.end(); ++it)  
  123.         {  
  124.             (*it)->Accept(status);  
  125.         }  
  126.     }  
  127. };  
  128.   
  129.   
  130. //测试代码  
  131. int main(int argc,char* argv[])  
  132. {  
  133.     ObjectStructure obj;  
  134.       
  135.     //加入要对比的两个种子  
  136.     obj.Attach(new Seed_A());  
  137.     obj.Attach(new Seed_B());  
  138.   
  139.     //查看各种状态下两个种子的情况  
  140.     obj.Display(new Rain_Status());  
  141.       
  142.     //Sun Satte  
  143.     obj.Display(new Sun_Status());  
  144.   
  145.     return 0;  
  146. }  

三. 说明

1. 首先有一点要明确,就是两种种子不会轻易改变,也就是只有普通和太空种子两种。换句话说就是,数据结构比较稳定

2. 可以变的是新增的状态,比如增加一个X光下的生成情况,等等。说白了就是,操作集合可以相对自由的演化

3. 这种结构的优点是,增加新的操作很容易;缺点是,增加新的数据结构有点困难,因为你要在每一个访问者里都添加相应的操作

4. 种子生长图相对于访问者模式的结构图有如下关系:

seed(种子)相当于 element(元素),这个是不怎么变的。

status(状态) 相当于 visitor(访问者),这个是可变且易变的。要注意的是,每个访问者都要对所有的元素(element)进行操作。

5. 事实上我们很少用这种模式,因为数据结构(element)不变的情况很少。


C++设计模式实现--访问者(Visitor)模式,布布扣,bubuko.com

C++设计模式实现--访问者(Visitor)模式

原文:http://blog.csdn.net/l_andy/article/details/36896645

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!