zoukankan      html  css  js  c++  java
  • 设计模式C++描述----22.访问者(Visitor)模式

    一. 访问者模式

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

    结构如下:


    二. 举例

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

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

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

    结构如下:


    代码如下:

    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)不变的情况很少。

  • 相关阅读:
    UVa 12174 (滑动窗口) Shuffle
    UVa 1607 (二分) Gates
    CodeForces ZeptoLab Code Rush 2015
    HDU 1525 (博弈) Euclid's Game
    HDU 2147 (博弈) kiki's game
    UVa 11093 Just Finish it up
    UVa 10954 (Huffman 优先队列) Add All
    CodeForces Round #298 Div.2
    UVa 12627 (递归 计数 找规律) Erratic Expansion
    UVa 714 (二分) Copying Books
  • 原文地址:https://www.cnblogs.com/any91/p/3248027.html
Copyright © 2011-2022 走看看