首页 > 代码库 > 设计模式实现C++ --策略模式Strategy(对象行为型)

设计模式实现C++ --策略模式Strategy(对象行为型)

1.问题

  出行旅游:我们可以有几个策略可以考虑:可以骑自行车,汽车,做火车,飞机。每个策略都可以得到相同的结果,但是它们使用了不同的资源。选择策略的依据

是费用,时间,使用工具还有每种方式的方便程度。

2.解决方案

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

  策略模式把对象本身和运算规则区分开来,其功能非常强大,因为这个设计模式本身的核心思想就是面向对象编程的多形性的思想。

  strategy模式类图:

        

3.应用场景

  1、 多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。

  2、需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。

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

4.组成

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

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

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

5.优缺点

  优点:

  1、 策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码转移到父类里面,从而避免重复的代码。
  2、 策略模式提供了可以替换继承关系的办法。继承可以处理多种算法或行为。如果不是用策略模式,那么使用算法或行为的环境类就可能会有一些子类,每一个子类提供一个不同的算法或行为。但是,这样一来算法或行为的使用者就和算法或行为本身混在一起。决定使用哪一种算法或采取哪一种行为的逻辑就和算法或行为的逻辑混合在一起,从而不可能再独立演化。继承使得动态改变算法或行为变得不可能。
  3、 使用策略模式可以避免使用多重条件转移语句。多重转移语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重转移语句里面,比使用继承的办法还要原始和落后。
  
  缺点:
  1、客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。
  2、 策略模式造成很多的策略类,每个具体策略类都会产生一个新类。有时候可以通过把依赖于环境的状态保存到客户端里面,而将策略类设计成可共享的,这样策略类实例可以被不同客户端使用。换言之,可以使用享元模式来减少对象的数量。
 
6.实现
 1 #include <iostream> 2 using namespace std; 3  4 class TravelStrategy 5 { 6 public: 7         virtual void travel() = 0; 8 }; 9 10 class AirPlanStrategy:public TravelStrategy11 {12 public:13         void travel()14         {15                 cout << "travel by air plan" << endl;16         }17 };18 19 class TrainStrategy:public TravelStrategy20 {21 public:22         void travel()23         {24                 cout << "travel by train" << endl;25         }26 };27 28 class BusStrategy:public TravelStrategy29 {30 public:31         void travel()32         {33                 cout << "travel by bus" << endl;34         }35 };enum TRAVEL {AIRPLAN, TRAIN, BUS};36 37 class PersonContext{38 public:39         PersonContext(enum TRAVEL tr)40         {41                 if(tr == AIRPLAN)42                         strategy = new AirPlanStrategy();43                 else if(tr == TRAIN)44                         strategy = new TrainStrategy();45                 else if(tr == BUS)46                         strategy = new BusStrategy();47                 else48                         strategy = NULL;49         }50 51         void travel()52         {53                 strategy->travel();54         }55 56 private:57         TravelStrategy* strategy;58 };
View Code