【转】设计模式学习笔记(21)-策略

策略(Strategy)模式十分类似于状态模式,它们俩的类图几乎完全一样,然而状态模式着重于对自身状态的变换引起行为的变化,而策略模式则强调不同类之间算法的不同导致可以采用不同的行为。状态模式在一个时间点处只有一种状态,而策略模式可以有多个策略。一个是时间概念,一个是空间概念。

策略模式:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。将多变的、复杂的算法逻辑抽离出主类,做成可插入式的以便达到复用的目的。

策略模式的类图如下(几乎和状态模式一模一样):

Strategy定义所有支持算法的公共接口,ConcreteStrategyX是具体实现类。Context定义上下文环境,它至少维护一个Strategy对象的引用。

示例代码如下:

1
2
3
4
5
class Strategy
{
public:
    virtual void DoAlgorithm() = 0;
};

这是算法公共接口,只有一个DoAlgorithm方法

1
2
3
4
5
6
7
8
9
10
11
12
class Context
{
private:
    Strategy* _strategy;
public:
    Context(Strategy* strategy) {
        this->_strategy =  strategy;
    }
    void DoSomething() {
        _strategy->DoAlgorithm();
    }
};

这是上下文环境,构造函数里面需要提供具体算法类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class ConcreteStrategyA : public Strategy
{
public:
    void DoAlgorithm() {
        cout << "This is strategy A" << endl;
    }
};
 
class ConcreteStrategyB : public Strategy
{
public:
    void DoAlgorithm() {
        cout << "This is strategy B" << endl;
    }
};

两个算法实现类,很简单,不必多说。

1
2
3
4
Context contexta(new ConcreteStrategyA);
contexta.DoSomething();
Context contextb(new ConcreteStrategyB);
contextb.DoSomething();

Main方法,最终输出为:

1
2
This is strategy A
This is strategy B

 

这个模式的关键是组合,以及面向接口。组合意味着可以随时更换对象(算法),有利于对象复用。同上一篇文章一样,策略模式也会带来大量的子类。这个示例并没有太多的逻辑,有时我们需要在算法对不同上下文有不同的表示,这时就需要对DoAlgorithm方法的参数做一些变动。

策略模式的适用性:

  • 许多相关的类仅仅是行为有异
  • 需要使用一个算法的不同变体
  • 算法使用客户不应该知道的数据
  • 一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现

不得不说条件语句是影响代码复杂性和可读性的一个重要因素,使用多个类可以避免这些麻烦,但可不可避免地带来了性能的下降。

 

转自:http://lecoding.com/articles/263.html

posted on 2013-03-05 16:35  TheKingOfKingFish  阅读(134)  评论(0)    收藏  举报

导航