策略模式 Strategy (举动型)

策略模式 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.策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换,策略模式让算法独立于使用它的客户而独立变化)

二 实例说明
策略模式 Strategy  (举动型)

Context(应用场景):
         需要使用ConcreteStrategy提供的算法。
         内部维护一个Strategy的实例。
         负责动态设置运行时Strategy具体的实现算法(或通过构造函数进行设置)。
         负责跟Strategy之间的交互和数据传递。

Strategy(抽象策略类):
         定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,Context使用这个接口调用不同的算法,一般使用接口或抽象类实现。

ConcreteStrategy(具体策略类):
         实现了Strategy定义的接口,提供具体的算法实现。 


对于Strategy模式来说,主要有这些应用场景:
1、  多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。
2、  需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。
3、  对客户(Context)隐藏具体策略(算法)的实现细节,彼此完全独立。
 
对于Strategy模式来说,主要有如下优点:
1、  提供了一种替代继承的方法,而且既保持了继承的优点(代码重用)还比继承更灵活(算法独立,可以任意扩展)。
2、  避免程序中使用多重条件转移语句,使系统更灵活,并易于扩展。
3、  遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。

对于Strategy模式来说,主要有如下缺点:
1、  因为每个具体策略类都会产生一个新类,所以会增加系统需要维护的类的数量。 

三 代码实现 

//
//  StrategyPattern.h
//  C++Demo
//
//  Created by zhangzhe on 14-4-1.
//  Copyright (c) 2014 Haifeng. All rights reserved.
//

#ifndef C__Demo_StrategyPattern_h
#define C__Demo_StrategyPattern_h

#include <iostream>
using namespace std;

//抽象算法类
class Strategy
{
public:
    virtual void AlgorithmInterface() = 0;
};

//具体算法A
class ConcreteStrategyA : public Strategy
{
public:
    virtual void AlgorithmInterface()
    {
        cout << "AlgorithmInterface A" << endl;
    }
};

//具体算法B
class ConcreteStrategyB : public Strategy
{
public:
    virtual void AlgorithmInterface()
    {
        cout << "AlgorithmInterface B" << endl;
    }
};

//具体算法C
class ConcreteStrategyC : public Strategy
{
public:
    virtual void AlgorithmInterface()
    {
        cout << "AlgorithmInterface C" << endl;
    }
};

//上下文
class Context
{
public:
    Context(Strategy *strategy)
    {
        this->strategy = strategy;
    }
    //上下文接口
    void ContextInterface()
    {
        strategy->AlgorithmInterface();
    }
private:
    Strategy *strategy;
};

void main()
{
    Context *context = new Context(new ConcreteStrategyA());
    context->ContextInterface();
   
    context = new Context(new ConcreteStrategyB());
    context->ContextInterface();
   
   
    context = new Context(new ConcreteStrategyC());
    context->ContextInterface();
}
#endif

四 总结

Program to an interface, not an implementation.(面向接口编程,而不要面向实现编程),接口是一个抽象的概念,不局限于语言层面的接口(例如C#里的interface)。一个接口也可以是一个抽象类,或者一个基类也可以看作是一种接口的表现形式,因为基类变量可以用来引用其子类。要点在于,我们在面向接口编程的时候,可以使用多态,那么实际运行的代码只依赖于具体的接口(interface,抽象类,基类),而不管这些接口提供的功能是如何实现的,也就是说,接口将系统的不同部分隔离开来,同时又将它们连接在一起,接口真是太伟大了!
   策略模式的定义Strategy接口,然后根据不同的功能来实现该接口,定义了一系列的可供重用的算法和行为。Context只和接口Strategy打交道。接口的实现对其来说是透明的。
   另外,策略模式的优点是简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。