设计模式 笔记 策略模式 Strategy

时间:2023-03-09 23:41:52
设计模式 笔记 策略模式 Strategy

//---------------------------15/04/28----------------------------

//Strategy 策略模式----对象行为型模式

/*

1:意图:

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

2:别名:

政策(Policy)

3:动机:

4:适用性:

1>许多相关的类仅仅是行为有异。策略提供了一种用多个行为中的一个行为来配置一个类的方法。

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

3>算法使用客户不应该知道的数据。使用策略模式可以避免暴露复杂的与算法相关的数据结构。

4>一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现。

将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。

5:结构:

Context:

strategy--------------------------->Strategy:

ContextInterface()                  AlgorithmInterface()

|

---------------------

|                   |

ConcteStrategyA:        ConcreteStrategyB:

AlgorithmInterface()    AlgorithmInterface()

6:参与者:

1>Strategy

定义所有支持的算法的公共接口。Context使用这个接口来调用某ConcreteStrategy定义的算法。

2>ConcreteStrategy:

根据Strategy定义的接口实现具体算法

3>Context

1)用一个ConcreteStrategy对象来配置。

2)维护一个对Strategy对象的引用。

3)可定义一个接口来让Strategy访问它的数据。

7:协作:

1>Strategy和Context相互作用以实现选定的算法,当算法被调用时,Context可以将该算法所需要的所有

数据都传递给该Strategy。或者使用自身来当作参数传给Strategy。

2>Context将它的客户的请求转发给它的Strategy。客户通常创建并传递一个ConcreteStrategy对象给

Context;这样客户可以仅与Context交互。

8:效果:

1>相关算法系列:

Strategy类层次为Context定义了一系列的可供重用的算法或行为。继承有助于析取出这些算法的公共功能

2>一个替代继承的方法:

如果使用继承来实现不同的算法,会导致Context难以理解,难以维护和难以扩展,并且算法和实现耦合很

深,所以Strategy模式很好的补足了这些部分。

3>消除了一些条件语句:

4>实现的选择:

Strategy可以提供相同行为的不同实现,客户可以根据不同时间/空间权衡取舍要求,从而选区不同的策略。

5>客户必须了解不同的Strategy:

这是Strategy模式潜在的一个缺点,客户必须熟知Strategy的实现才能正确选择什么Strategy。

6>Strategy和Context的通信开销:

一些简单的Strategy可能不需要参数,但是为了别的Strategy考虑,Context和Strategy之间

通信的接口必须要“通用”,也就是考虑到所有的参数,所以这可能造成浪费。

7>增加了对象的数目:

Strategy增加了应用中的对象的数目。可采用Flyweight来减少开销。

9:实现:

1>定义Strategy和Context接口:

1)传递一些数据:

Context可能会发送一些Strategy不需要的数据。这个方法通过加大开销来解耦两个类

2)传递自己,或在Strategy中存放一个Context的引用:

这样Strategy和Context会更紧密地耦合在一起。

2>将Strategy作为模版参数:

这样必须满足两点:

1)可以在编译时选择Strategy

2)不需要在运行时改变

这就是属于编译器多态。

3>使Strategy对象称为可选的:

如果即使不使用Strategy对象Context还是有意义的话,可以简化Context,让Context在访问Strategy

前检查是否存在,有就使用,没有就执行缺省的行为。

10:代码示例:                                                                        */

//Context:
里面保存了一个Compositior类的指针,也就是一个ConcreteStrategy

class Composition

{

public:

Composition(Compositior*);

void Repair();

private:

Compositior* _compositor;

Component* _components;

int _componentCount;

int _lineWidth;

int* _lineBreaks;

int _lineCount;

};

//Abstract Strategy

class Compositor

{

public:

virtual int Compose(Coord natural[],Coord stretch[], Coord shrink[],

int componentCount,
int lineWidth, ;

protected:

compositor();

};

//这里使用到了Strategy的操作,Compose()

void Composition::Repair()

{

Coord* natural;

Coord* stretchability;

Coord* shrinkability;

int componentCount;

int* breaks;

int breakCount;

breakCount = _compositor->Compose(natural, stretchability, shrinkability

componentCount, _lineWidth, breaks);

}

//ConcreteStrategy:自己实现自己的Compose具体怎么做

class SimpleCompositor : Compositor

{

public:

SimpleCompositor();

virtual int Compose(Coord natural[],Coord stretch[], Coord shrink[],

int componentCount,
int lineWidth, int breaks[]);

};

class TexCompositor : Compositor

{

TexCompositor();

virtual int Compose(Coord natural[],Coord stretch[], Coord shrink[],

int componentCount,
int lineWidth, int breaks[]);

};

class ArrayCompositor : Compositor

{

ArrayCompositor(int interval);

virtual int Compose(Coord natural[],Coord stretch[], Coord shrink[],

int componentCount,
int lineWidth, int breaks[]);

};

//简单的使用,但是每次都要new一个Strategy对象,可以使用Flyweight模式优化

Composition* quick =
new Composition(new SimpleCompositor);

Composition* slick =
new Composition(new TexCompositor);

Composition* iconic =
));