[行为模式] head first 设计模式之策略模式(strategy)

1 概念
    策略模式(Strategy):它定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法的变化不会影响到使用算法的客户。(原文:The Strategy Pattern defines a family of algorithms,encapsulates each one,and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.)

2 策略模式的结构
   封装类:也叫上下文,对策略进行二次封装,目的是避免高层模块对策略的直接调用。
   抽象策略:通常情况下为一个接口,当各个实现类中存在着重复的逻辑时,则使用抽象类来封装这部分公共的代码,此时,策略模式看上去更像是模版方法模式。
   具体策略:具体策略角色通常由一组封装了算法的类来担任,这些类之间可以根据需要自由替换。

3 设计原则
  a) 找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起;
  b) 针对借口编程,而不是针对实现编程;
  c) 多用组合,少用继承;
  d) 含有许多条件语句(if-else)的代码意味着需要使用Strategy模式


[行为模式] head first 设计模式之策略模式(strategy)_第1张图片

示例代码:

#ifndef   STRATEGY_H
#define   STRATEGY_H

#include <iostream>
using namespace std;

//策略模式
namespace Strategy
{

//////////////////////////////////////////////////////////////////////////
class FlyBehavior
{
public:
    virtual void fly() = 0;
};

class FlyWithWings : public FlyBehavior
{
public:
    virtual void fly() { cout << "I'm flying!!" << endl; }
};

class FlyNoWay : public FlyBehavior
{
public:
    virtual void fly() { cout << "I can't fly!" << endl; }
};

class FlyRocketPowred : public FlyBehavior
{
public:
    virtual void fly() { cout << "I'm flying with a rocket!" << endl; }
};

//////////////////////////////////////////////////////////////////////////
class QuackBehavior
{
public:
    virtual void quack() = 0;
};

class Quack : public QuackBehavior
{
public:
    virtual void quack() { cout << "Quack" << endl;}
};

class MuteQuack : public QuackBehavior
{
public:
    virtual void quack() { cout << "<<Silence>>" << endl; }
};

class Squack : public QuackBehavior
{
public:
    virtual void quack() { cout << "Squack" << endl;}
};

//////////////////////////////////////////////////////////////////////////
class Duck
{
public:
    Duck(){}
    virtual ~Duck(){}

    virtual void display() = 0;
    virtual void performFly()
    {
        if ( m_FlyBehavior != NULL)
        {
            m_FlyBehavior->fly();
        }
    }
    virtual void performQuack()
    {
        if ( m_QuackBehavior != NULL)
        {
            m_QuackBehavior->quack();
        }
    }
    virtual void swim() { cout << "All ducks float, even decoys!" <<endl; }

    virtual void setFlyBehavior(FlyBehavior* fb)
    {
        if (fb != NULL)
        {
            delete m_FlyBehavior;
            m_FlyBehavior = fb;
        }
    }

    virtual void setQuackBehavior(QuackBehavior* qb)
    {
        if (qb != NULL)
        {
            delete m_QuackBehavior;
            m_QuackBehavior = qb;
        }
    }

protected:
    FlyBehavior*   m_FlyBehavior;
    QuackBehavior* m_QuackBehavior;
};

class MallardDuck : public Duck
{
public:
    MallardDuck()
    {
        m_QuackBehavior = new Quack();
        m_FlyBehavior   = new FlyWithWings();
    }
    virtual ~MallardDuck()
    {
        if (m_FlyBehavior != NULL)
        {
            delete m_FlyBehavior;
            m_FlyBehavior = NULL;
        }

        if (m_QuackBehavior != NULL)
        {
            delete m_QuackBehavior;
            m_QuackBehavior = NULL;
        }
    }

    virtual void display() { cout << "I'm a real Mallard duck" << endl; }
};

class ModelDuck : public Duck
{
public:
    ModelDuck()
    {
        m_FlyBehavior   = new FlyNoWay();
        m_QuackBehavior = new Quack();
    }
    virtual ~ModelDuck()
    {
        if (m_FlyBehavior != NULL)
        {
            delete m_FlyBehavior;
            m_FlyBehavior = NULL;
        }

        if (m_QuackBehavior != NULL)
        {
            delete m_QuackBehavior;
            m_QuackBehavior = NULL;
        }
    }

    virtual void display()
    {
        cout << "I'm a model duck"  << endl;
    }
};

//////////////////////////////////////////////////////////////////////////
class MiniDuckSimulator
{
public:
    void run()
    {
        //UnitTest1
        Duck* pMallard = new MallardDuck();
        pMallard->performQuack();
        pMallard->performFly();
        delete pMallard;

        //UnitTest2
        Duck* pModel = new ModelDuck();
        pModel->performFly();
        pModel->setFlyBehavior(new FlyRocketPowred());
        pModel->performFly();
        delete pModel;
    }

};

}//namespace Strategy

#endif

你可能感兴趣的:(strategy)