首页 > 代码库 > 策略模式

策略模式

定义

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

角色

环境类(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     virtual double GetResult() = 0; };  7 //加法  8 class AddOperation : public COperation  9 { 10 public: 11     virtual double GetResult() 12     { 13         return m_nFirst + m_nSecond; 14     } 15 }; 16 //减法 17 class SubOperation : public COperation 18 { 19 public: 20     virtual double GetResult() 21     { 22         return m_nFirst - m_nSecond; 23     } 24 }; 25  26 // 策略模式 27 class Context 28 { 29 private: 30     COperation* op; 31 public: 32     Context(COperation* temp) 33     { 34         op = temp; 35     } 36     double GetResult() 37     { 38         return op->GetResult(); 39     } 40 } 41  42 // 策略+工厂 43 class Context 44 { 45 private: 46     COperation* op; 47 public: 48     Context(char cType) 49     { 50         switch(cType) 51         { 52         case +: 53             op = new AddOperation(); 54             break; 55         case -: 56             op = new SubOperation(); 57             break; 58         default: 59             break; 60         } 61     }  62     double GetResult() 63     { 64         return op->GetResult(); 65     } 66 }; 67  68 //简单工厂模式的工厂类 69 class CCalculatorFactory 70 { 71 public: 72     static COperation* Create(char cOperator); 73 }; 74  75 COperation* CCalculatorFactory::Create(char cOperator) 76 { 77     COperation *oper; 78      79     switch (cOperator) 80     { 81     case +: 82         oper=new AddOperation(); 83         break; 84     case -: 85         oper=new SubOperation(); 86         break; 87     default: 88         oper=new AddOperation(); 89         break; 90     } 91     return oper; 92 } 93  94 //工厂模式的工厂类 95 class CCalculatorFactory 96 { 97 public: 98     virtual COperation* Create() = 0; 99 };100 101 class AddFactory : public CCalculatorFactory102 {103 104 public:105     COperation* Create()106     {107         return new AddOperation;108     }109 };110 111 class SubFactory : public CCalculatorFactory112 {113 public:114     virtual COperation* Create()115     {116         return new SubOperation;117     }118 };119 120 // 客户端121 int main()122 {123     int a,b;124     cin>>a>>b;125     // 简单工厂模式       126     COperation * op = CCalculatorFactory::Create(-);127 128     // 工厂方法模式129     CCalculatorFactory* p = new AddFactory;130     COperation* opr = p->Create();131 132    // 策略模式133    cin>>c;134     switch(c)135    {136    case +:137     Context *context = new Context(new AddOperation());138     break;139    case -:140     Context *context = new Context(new SubOperation());141     break;142    default:143     break;144    }145 146    // 策略+工厂模式147    Context *contest = new Context(+);148   149 150 151    opr->m_nFirst=a; 152 153    opr->m_nSecond=b; 154 155    cout<<op->GetResult()<<endl; 156 157    return 0; 158 159 }

 

 

策略模式