UML类图(仅供参考)如下:
策略模式解决的问题:
如果系统中的一些类仅仅在行为或算法上面有微微的不同,那么我们可以把这些相似的类和这些行为或算法抽象出来,然后在程序运行的过程中动态的选择使用哪种行为或算法
源码
#include <iostream>
// 抽象算法
class CStrategy
{
public:
virtual ~CStrategy() {}
// 这里需要你根据实际情况定义算法的接口形式
virtual void Algorithm() = 0;
};
// 具体算法A
class CConcreteStrategyA :public CStrategy
{
public:
virtual void Algorithm()
{
std::cout << "我是算法A" << std::endl;
}
};
// 具体算法B
class CConcreteStrategyB :public CStrategy
{
public:
virtual void Algorithm()
{
std::cout << "我是算法B" << std::endl;
}
};
// 具体算法C
class CConcreteStrategyC :public CStrategy
{
public:
virtual void Algorithm()
{
std::cout << "我是算法C" << std::endl;
}
};
// 策略选择
class CContext
{
public:
CContext() :m_pStrategy(NULL) {}
~CContext()
{
if (NULL != m_pStrategy)
{
delete m_pStrategy;
m_pStrategy = NULL;
}
}
// 用于输入策略,然后选择相应的算法对象
// 这里把字符串的值当成是一种策略
void ContextInterface(const std::string &sJudge)
{
if (NULL != m_pStrategy)
{
delete m_pStrategy;
m_pStrategy = NULL;
}
if ("A" == sJudge)
{
m_pStrategy = new CConcreteStrategyA();
}
else if("B" == sJudge)
{
m_pStrategy = new CConcreteStrategyB();
}
else if ("C" == sJudge)
{
m_pStrategy = new CConcreteStrategyC();
}
else
{
// ...
}
}
// 根据上面方法的策略获得对应的算法对象
// 根据算法对象计算结果值
void GetResult()
{
m_pStrategy->Algorithm();
}
private:
CStrategy *m_pStrategy;
};
int main()
{
CContext context;
context.ContextInterface("A");
context.GetResult();
context.ContextInterface("B");
context.GetResult();
context.ContextInterface("C");
context.GetResult();
return 0;
}
好处
在策略模式中,所有算法都将是继承同一个父类,这样就可以任意添加新的算法,而不影响其他算法。对于CContext类,虽然要修改ContextInterface方法,也不满足开放封闭原则,但这是为了让选择策略在CContext中完成,让客户端只需要知道CContext一种类,不用知道具体的算法类。当然你可以不这么做,将策略的选择放在其他地方,也不会有太大的改动,当然在这个地方,如果配合着简单工厂模式或者工厂模式一起用,显得更好一些