zoukankan      html  css  js  c++  java
  • 策略模式

    定义

      策略模式,又叫算法簇模式,就是定义了不同的算法族,并且之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
      策略模式的重心不是如何实现算法,而是如何组织、调用这些算法,从而让程序结构更灵活,具有更好的维护性和扩展性。

    角色

      环境类(Context):用一个ConcreteStrategy对象来配置。维护一个对Strategy对象的引用。可定义一个接口来让Strategy访问它的数据。

      抽象策略类(Strategy):定义所有支持的算法的公共接口。 Context使用这个接口来调用某ConcreteStrategy定义的算法。

      具体策略类(ConcreteStrategy):以Strategy接口实现某具体算法。

    使用场景

      当存在以下情况时使用Strategy模式

      1、多个类只区别在表现行为不同。 “策略”提供了一种用多个行为中的一个行为来配置一个类的方法。

      2、需要使用一个算法的不同变体。

      3、对客户(Duck)隐藏具体策略(算法)的实现细节,彼此完全独立。

      4、一个类定义了多种行为 , 且这些行为在该类的操作中以多个条件语句的形式出现。将相关条件分支移入它们各自的Strategy类中以代替这些条件语句。

    优缺点

      对于Strategy模式来说,主要有如下优点:

      1、  提供了一种替代继承的方法,而且既保持了继承的优点(代码重用)还比继承更灵活(算法独立,可以任意扩展)。

      2、  避免程序中使用多重条件转移语句,使系统更灵活,并易于扩展。

      3、  遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。
     

      对于Strategy模式来说,主要有如下缺点:

      1、因为每个具体策略类都会产生一个新类,所以会增加系统需要维护的类的数量。

      2、客户端必须知道所有的策略类,并自行决定使用哪一个策略类:  

    与状态模式的比较

      1、策略模式只是在对象初始化的时候更改执行模式,而状态模式是根据对象实例的周期时间而动态地改变对象实例的执行模式。

      2、使用策略模式时,客户端需要知道所选的具体策略是哪一个,而使用状态模式时,客户端无须关心具体状态,环境类的状态会根据用户的操作自动转换。

      3、如果系统中某个类的对象存在多种状态,不同状态下行为有差异,而且这些状态之间可以发生转换时使用状态模式;
         如果系统中某个类的某一行为存在多种实现方式,而且这些实现方式可以互换时使用策略模式。
     
    策略模式、简单工厂模式、工厂方法模式、策略模式与工厂模式结合代码比较
      
      
      为了方便比较,将四种模式的代码放到一起,通过同一个例子来说明。
      
      1 class COperation
      2 {
      3 public:
      4     int m_nFirst;
      5     int m_nSecond;
      6 
      7     virtual double GetResult() = 0; 
      8 };
      9 //加法
     10 class AddOperation : public COperation
     11 {
     12 public:
     13     AddOperation(int a,int b)
     14     {
     15         m_nFirst = a;
     16         m_nSecond = b;
     17     }
     18     
     19     virtual double GetResult()
     20     {
     21         return m_nFirst + m_nSecond;
     22     }
     23 };
     24 //减法
     25 class SubOperation : public COperation
     26 {
     27 public:
     28     SubOperation(int a,int b)
     29     {
     30         m_nFirst = a;
     31         m_nSecond = b;
     32     }
     33 
     34     virtual double GetResult()
     35     {
     36         return m_nFirst - m_nSecond;
     37     }
     38 };
     39 
     40 /*************************************************/
     41 // 1.策略模式的实现-策略模式的环境类
     42 class Context
     43 {
     44 private:
     45     COperation* op;
     46 public:
     47     Context(COperation* temp)
     48     {
     49         op = temp;
     50     }
     51     double GetResult()
     52     {
     53         return op->GetResult();
     54     }
     55 }
     56 /*************************************************/
     57 // 2.简单工厂模式的实现-简单工厂模式的工厂类
     58 class CCalculatorFactory
     59 {
     60 public:
     61     static COperation* Create(char cOperator ,int a ,int b);
     62 };
     63 
     64 COperation* CCalculatorFactory::Create(char cOperator, int a, int b)
     65 {
     66     COperation *oper;
     67     
     68     switch (cOperator)
     69     {
     70     case '+':
     71         oper=new AddOperation(a, b);
     72         break;
     73     case '-':
     74         oper=new SubOperation(a, b);
     75         break;
     76     default:
     77         break;
     78     }
     79     return oper;
     80 }
     81 /*************************************************/
     82 // 3.工厂模式的工厂类
     83 class CCalculatorFactory
     84 {
     85 public:
     86     virtual COperation* Create(int a, int b) = 0;
     87 };
     88 
     89 class AddFactory : public CCalculatorFactory
     90 {
     91 
     92 public:
     93     COperation* Create(int a, int b)
     94     {
     95         return new AddOperation(a, b);
     96     }
     97 };
     98 
     99 class SubFactory : public CCalculatorFactory
    100 {
    101 public:
    102     virtual COperation* Create(int a, int b)
    103     {
    104         return new SubOperation(a, b);
    105     }
    106 };
    107 /*************************************************/
    108 // 4.策略+工厂的实现
    109 class Context
    110 {
    111 private:
    112     COperation* op;
    113 public:
    114     Context(char cType, int a, int b)
    115     {
    116         switch(cType)
    117         {
    118         case '+':
    119             op = new AddOperation(a, b);
    120             break;
    121         case '-':
    122             op = new SubOperation(a, b);
    123             break;
    124         default:
    125             break;
    126         }
    127     } 
    128     double GetResult()
    129     {
    130         return op->GetResult();
    131     }
    132 };
    133 /*************************************************/
    134 
    135 // 客户端
    136 int main()
    137 {
    138     int a,b;
    139     cin>>a>>b;
    140     // 简单工厂模式       
    141     COperation * op = CCalculatorFactory::Create('-', a, b);
    142     cout<<op->GetResult()<<endl; 
    143 
    144     // 工厂方法模式
    145     CCalculatorFactory* p = new AddFactory;
    146     COperation* op = p->Create(a, b);
    147     cout<<op->GetResult()<<endl; 
    148 
    149     // 策略模式
    150     cin>>c;
    151     Context *context; 
    152     switch(c)
    153     {
    154     case '+':
    155         context = new Context(new AddOperation(a, b));
    156         break;
    157     case '-':
    158         context = new Context(new SubOperation(a, b));
    159         break;
    160     default:
    161         break;
    162     }
    163     cout<<context->GetResult()<<endl; 
    164     
    165     // 策略+工厂模式
    166     Context *context = new Context('+', a, b);
    167     cout<<context->GetResult()<<endl; 
    168 
    169     return 0; 
    170 
    171 }    
     
     
     
     
     
  • 相关阅读:
    Delphi XE5 android 蓝牙通讯传输
    Delphi XE5 android toast
    Delphi XE5 android openurl(转)
    Delphi XE5 如何设计并使用FireMonkeyStyle(转)
    Delphi XE5 android 捕获几个事件
    Delphi XE5 android listview
    Delphi XE5 android 黑屏的临时解决办法
    Delphi XE5 android popumenu
    Delphi XE5 android 获取网络状态
    Delphi XE5 android 获取电池电量
  • 原文地址:https://www.cnblogs.com/SnailProgramer/p/4246079.html
Copyright © 2011-2022 走看看