1.什么事策略模式
策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。这是百度百科的解释,我的理解是,我们要事先制定一系列的方法,我们要根据我们的需要,进行输入,然后能够调用出不出的事先写好的策略出来(策略的实现独立于客户,客户只能够进行调用)。
2. 策略模式的实现
下面举例来说明策略模式。我们的目标是制定三种策略,使得根据用户的需求不同而调用不同的策略。首先,我们要设计一个策略的终极父类。
#include <cstdio>
#include <iostream>
#include <map>
using namespace std;
class Strategy
{
public:
virtual void Algorithm() = 0;
};
然后,我们要制定策略的子类,继承终极父类。
class StrategyA:public Strategy
{
public:
virtual void Algorithm()
{
cout<<"this is A Strategy"<<endl;
}
};
class StrategyB:public Strategy
{
public:
virtual void Algorithm()
{
cout<<"this is B Strategy"<<endl;
}
};
class StrategyC:public Strategy
{
public:
virtual void Algorithm()
{
cout<<"this is C Strategy"<<endl;
}
};
这样我们就将策略整理好了,下面我们就要根据不同输入类调用不同的策略,实现如下:
class Context
{
public:
Context(Strategy *s)
{
str = s;
}
void dowork()
{
str->Algorithm();
}
private:
Strategy *str;
};
int main(int argc, char const *argv[])
{
Context *cnt;
cnt = new Context( new StrategyA() );
cnt->dowork();
cnt = new Context( new StrategyB() );
cnt->dowork();
cnt = new Context( new StrategyC() );
cnt->dowork();
return 0;
}
这个时候,一个策略模式就完成了,但是我们会发现以这样的一个问题,在main函数中,我们直接调用的new来实例化一个策略,使用这种方法,仍然将策略函数的接口暴露在外,因此这个程序还需要改进。
3.简单工厂模式与策略模式的配合
为了改进上面的问题,我们可以采用简单点的工程模式来统一生产出合适的对象,改进如下:、
class Context
{
public:
Context(string tmpstr)
{
std::map<string, int> mp;
mp["A"] = 1;
mp["B"] = 2;
mp["C"] = 3;
switch(mp[tmpstr])
{
case 1: {str = new StrategyA;break;}
case 2: {str = new StrategyB;break;}
case 3: {str = new StrategyC;break;}
}
}
void dowork()
{
str->Algorithm();
}
private:
Strategy *str;
};
int main(int argc, char const *argv[])
{
Context *cnt;
string s = "C";
cnt = new Context(s);
cnt->dowork();
return 0;
}
这样进一步的降低的程度的耦合度,成功的将策略的接口隐藏掉,Context成为一个工厂,生产出我们需要的对象。
我的魔法已为空,剩下只是挥舞的手臂。 --MPoooooo