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


    版权声明:本文为博主原创文章,未经博主同意不得转载。

    https://blog.csdn.net/L_Andy/article/details/36896645

    一. 訪问者模式

    定义:表示一个作用于某对象结构中的各元素的操作。

    它你能够在不改变各元素的类的前提下定义作用于这些元素的新操作。

    结构例如以下:


    二. 举例

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

    两种种子。一种是普通的种子(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. 这样的结构的长处是。添加新的操作非常easy。缺点是,添加新的数据结构有点困难,由于你要在每个訪问者里都加入对应的操作

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

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


    status(状态) 相当于 visitor(訪问者),这个是可变且易变的。

    要注意的是,每个訪问者都要对全部的元素(element)进行操作。

    5. 其实我们非常少用这样的模式。由于数据结构(element)不变的情况非常少。


  • 相关阅读:
    全面解释java中StringBuilder、StringBuffer、String类之间的关系
    如何解决Java.lang.NoClassDefFoundError--第一部分
    Java中Vector和ArrayList的区别
    深入研究java.lang.ThreadLocal类
    Frame.pack()与frame.validate()方法的区别
    Oracle中start with...connect by子句的用法
    Java 的swing.GroupLayout布局管理器的使用方法和实例
    Java SE 6.0实现高质量桌面集成开发
    苹果App Store开发者帐户从申请,验证,到发布应用(2)
    苹果App Store开发者帐户从申请,验证,到发布应用(1)
  • 原文地址:https://www.cnblogs.com/mqxnongmin/p/10664007.html
Copyright © 2020-2023  润新知