在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。
意图
定义一系列的算法,把它们一个个封装起来,并且使他们可以互相替换
解决问题
在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护
如何解决
将这些算法封装成一个一个的类,任意地替换
优点
1. 算法可以自由切换
2. 避免使用多重条件
3. 扩展性好
缺点
1. 策略类会增多
2. 所有策略类都需要对外暴露
使用场景
1. 如果在一个系统里面有很多类,它们之间的区别仅在于它们的行为,么使用策略模式可以动态地让一个对象在许多行为中选择一种行为;
2. .需要使用一个算法的不同变体;
3. 算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构
4. 个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以替代这些条件语句。(是不是和状态模式有点一样哦?)
注意事项
如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题
UML类图
Strategy : 定义所有支持的算法的公共接口;
Context : 使用这个接口调用ConcreteStrategy定义的算法;
使用一个ConcreteStrategy对象类配置;维护一个Strategy对象的引用,同时可定义一个接口让 Strategy来访问它的数据;
ConcreteStrategy :实现Strategy接口的具体算法;
C++实现
//策略模式
class Strategy //抽象策略
{
public:
virtual void AlgorithmInterface() = 0;
};
class StrategyA : public Strategy // 具体策略
{
public:
void AlgorithmInterface()
{
cout << "I am from StrategyA." << endl;
}
};
class StrategyB : public Strategy
{
public :
void AlgorithmInterface()
{
cout <<"I am from StrategyB."<< endl;
}
};
class StrategyC : public Strategy
{
public:
void AlgorithmInterface()
{
cout << "I am from StrategyC." << endl;
}
};
class _Context
{
Strategy* pStrategy;
public :
_Context(Strategy* _pStrategy)
:pStrategy(_pStrategy)
{}
void ContextInterface()
{
pStrategy->AlgorithmInterface();
}
};
客户端:
int test_Strategy() //策略 模式
{
//创建策略
Strategy* pStrategyA = new StrategyA;
Strategy* pStrategyB = new StrategyB;
Strategy* pStrategyC = new StrategyC;
_Context* pContextA = new _Context(pStrategyA);
_Context* pContextB = new _Context(pStrategyB);
_Context* pContextC = new _Context(pStrategyC);
pContextA->ContextInterface();
pContextB->ContextInterface();
pContextC->ContextInterface();
if (pStrategyA) delete pStrategyA;
if (pStrategyB) delete pStrategyB;
if (pStrategyC) delete pStrategyC;
if (pContextA) delete pContextA;
if (pContextB) delete pContextB;
if (pContextC) delete pContextC;
system("pause");
return 0;
}
总结:
略模式和状态模式很相似;状态模式强调的是状态的变化,不同状态下执行不同的行为;而策略模式侧重的是同一个动作,现在呢该行为的算法的不同,不同的策略封装不同的算法。
策略模式适用于实现某一功能,而实现该功能的算法是经常改变的情况。在实际工作中,遇到了实际的场景,可能会有更深的体会。比如,我们做某一个系统,该系统可以适用于各种数据库,我们都知道,连接某一种数据库的方式是不一样的,也可以说,连接数据库的“算法”都是不一样的。这样,我们就可以使用策略模式来实现不同的连接数据库的策略,从而实现数据库的动态变换。