策略模式 Strategy (举动型)
策略模式 Strategy (行为型)
一 策略模式定义

Context(应用场景):
对于Strategy模式来说,主要有这些应用场景:
//
// 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();
}
一 策略模式定义
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.(策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换,策略模式让算法独立于使用它的客户而独立变化)
二 实例说明
需要使用ConcreteStrategy提供的算法。
内部维护一个Strategy的实例。
负责动态设置运行时Strategy具体的实现算法(或通过构造函数进行设置)。
负责跟Strategy之间的交互和数据传递。
Strategy(抽象策略类):
定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,Context使用这个接口调用不同的算法,一般使用接口或抽象类实现。
ConcreteStrategy(具体策略类):
实现了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打交道。接口的实现对其来说是透明的。
另外,策略模式的优点是简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。