最常用的设计模式-----策略模式(C++实现)

策略模式也是一种非常常用的设计模式,而且也不复杂。下面我们就来看看这种模式。

定义:策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

角色:
    抽象策略角色(Strategy): 抽象策略类。
    具体策略角色(ConcreteStrategy):封装了继续相关的算法和行为。
    环境角色(Context):持有一个策略类的引用,最终给客户端调用。

UML图:

                

事例: (该事例改编自一道网络设计模式面试题)

     如现在你是一个设计师,你正在设计一种空调。但是你们的空调要支持3种模式。冷风模式(ColdWind), 热风模式(WramWind),无风模式(NoWind)。
当选择ColdWind模式,将输送冷风;当选择WarmWind模式,将输送热风;在选择NoWind模式时,空调什么都不做。你将考虑如何为空调设计应用程序?如果将来空调需要增加支持新的模式呢?

这道面试题,其实可以用各种模式实现,然而在这里我理解策略模式比较合适。我们将冷风模式,和热风模式以及无风模式可以理解为各种不同的算法。显然策略模式非常符合。

这里ColdWind, WramWind, NoWind 其实就是ConcreteStrategy。 IWnd 是抽象策略类。 所以我们开始这么封装我们策略类

[cpp]  view plain  copy
  1. #include <iostream>  
  2. using namespace std;  
  3. #define  free_ptr(p) \  
  4.     if(p) delete p; p = NULL;  
  5.   
  6. class IWind{  
  7. public:  
  8.     virtual ~IWind(){};  
  9.     virtual void blowWind() = 0;  
  10. };  
  11.   
  12. class ColdWind : public IWind{  
  13. public:  
  14.     void blowWind(){  
  15.         cout<<"Blowing cold wind!"<<endl;  
  16.     };  
  17. };  
  18.   
  19. class WarmWind : public IWind{  
  20. public:  
  21.     void blowWind(){  
  22.         cout<<"Blowing warm wind!"<<endl;  
  23.     }  
  24. };  
  25.   
  26. class NoWind : public IWind{  
  27. public:  
  28.     void blowWind(){  
  29.         cout<<"No Wind!"<<endl;  
  30.     }  
  31. };  

然后我们实现一个windmode 的类,作为 wind 系列的环境类:

[cpp]  view plain  copy
  1. class WindMode{  
  2. public:  
  3.     WindMode(IWind* wind): m_wind(wind){};  
  4.     ~WindMode(){free_ptr(m_wind);}  
  5.     void blowWind(){  
  6.         m_wind->blowWind();  
  7.     };  
  8. private:  
  9.     IWind* m_wind;  
  10. };  

最后客户端代码:

[cpp]  view plain  copy
  1. int main(int argc, char* argv[])  
  2. {  
  3.     WindMode* warmWind = new WindMode(new WarmWind());  
  4.     WindMode* coldWind = new WindMode(new ColdWind());  
  5.     WindMode* noWind = new WindMode(new NoWind());  
  6.   
  7.     warmWind->BlowWind();  
  8.     coldWind->BlowWind();  
  9.     noWind->BlowWind();  
  10.   
  11.     free_ptr(warmWind);  
  12.     free_ptr(coldWind);  
  13.     free_ptr(noWind);  
  14.     system("pause");  
  15.     return 0;  
  16. }  

      (这个实例网上也有人用命令模式实现。命令模式请看我后面的博客。把冷风,热风,无风作为一种命令。当然这是另外一种思路,也未尝不可。但是我觉得如果采用命令模式。类的个数会相应增加(增加系列的命令类),照成额外的开销。当添加一个新模式的时候,你需要添加的类过多。或多或少不是那么明智。所以我个人认为在这里策略模式更好一些。)

总的说来策略模式:

优点:
1、 使用策略模式可以避免使用多重条件转移语句。多重转移语句不易维护。
2、 策略模式让你可以动态的改变对象的行为,动态修改策略

缺点:
1、客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
2、类过多---策略模式造成很多的策略类,每个具体策略类都会产生一个新类。(这点可以通过享元模式来克服类过多)


猜你喜欢

转载自blog.csdn.net/sunxiaopengsun/article/details/80391274