策略模式(strategy):
属于行为模式
意图:
定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。本模式使得算法可独立于它的客户而变化。
什么意思呢,我想的是,算法独立于客户,我们把一些算法具体实现封装起来,成为具体的类,而每一个算法独立为一种具体策略,把算法和环境(context)独立开来,这样有利于算法的扩展,很明显,这种模式很适合用于策略容易发生变化的业务。还是以具体的实例做基础吧。
假设这样的业务,游乐场,我们针对不同的项目,计算不同的开销,其实我不了解具体开销是不是以算法的形式,但是我们假设每一种开销有一种固定算法。假设一开始,我们支持过山车,碰碰车,海盗船,最简单的实现是这样:
enum GameType {
Roller,
PoCar,
PirateShip,
//更改
};
class Economic:
{
private:
GameType _g_Type;
public:
double caculateOut()
{
switch(_g_Type)
{
case Roller:
//算法1
break;
case PoCar:
//算法2
break;
case PirateShip:
//算法3
break;
}
}
}
当然这样也是可以实现,但是这样不好,如果我们需要支持更多的项目,我们还要加多的枚举type,然后新增加一个case,比如*落体项目,那还得修改代码。很明显违背了"开放封闭原则"。这样的例子是最好用策略模式的,首先,这里的确需要多种算法(策略),并且算法可能增加(变化)。运用策略模式,那么我们首先需要抽象一个策略基类。然后将算法从环境类(这里是Economic)里面分离出来,在策略基类中实现它们。
所以,改成这样是不是好一点:
定义抽象策略类。
class TypeStrategy
{
public:
virtual double calculate()=0;
~virtual TypeStrategy;
}
将已有业务算法实现:
class RollerStrategy:public TypeStrategy
{
public:
double calculate()
{
//具体实现
}
}
class PocarStrategy:public TypeStrategy
{
public:
double calculate()
{
//具体实现
}
}
class PirateShipStrategy:public TypeStrategy
{
public:
double calculate()
{
//具体实现
}
}
定义算法的执行环境类:
class Economic
{
private:
TypeStrategy *_stgy;
public:
Economic(StrategyFactory* factory)
{
_stgy = factory->setup();
}
~Economic()
{
delete _stgy;
}
double calculateOut()
{
return _stgy->calculate();
}
}
如果有必要,还得定义一个context对象来保证算法和类之间的数据。
现在,我们假设需要增加一个项目,比如是鬼屋。
我们只需要定义我们的算法即可,做如下改动:
//扩展
class ShriedStrategy:public TypeStrategy
{
public:
double calculate()
{
//具体实现
}
}
而不需要对别的地方进行改动。保证了"开放封闭原则"。
书上给的策略模式结构图是这样的:
可以看到实现context和strategy的分离,然后对strategy进行抽象。