策略模式(Strategy)
策略模式(Strategy)[Policy]
意图:定义一系列算法,把他们封装起来,并且使他们可以相互替换,使算法可以独立于使用它的客户而变化。
应用:排序的比较方法、封装针对类的不同的算法、消除条件判断、寄存器分配算法等。
模式结构:
心得:
对对象(Context)的处理操作可能有很多方式,这些方式很多情况下是同一类的处理操作,区别仅仅是操作的具体内容的差别。一般会通过条件分支判断不同的算法或者使用继承产生不同处理算法对应的对象。但是这么做的扩展性都很差,如果把对同一数据的不同处理方式封装起来,继承于统一的接口,就可以封装这些变化,达到扩展性的目的。
举例:
被处理的Context对象可以看作一组数据,现在需要对该数据进行排序,但是排序的方式无法确定。也就说如何比较元素的大小是由用户来选择的,那么用户选择的变化性可以封装在具体的策略对象ConcreteStrategy内部,根据用户选择生成不同方式的策略对象,然后Context只需要一个抽象的Strategy引用该对象,操作它的接口来决定排序的方式就可以了。
这里涉及Context类和Strategy交互的问题,Context需要Strategy提供的算法进行计算,那么源数据如何告知Strategy类就有两种方式:一种是通过参数传递,直接将数据传参到Strategy的接口algorithmInteface即可,另一种是直接传递Strategy对象的指针,并提供公共的访问接口contextInterface来提供数据来源。最后通过algorithmInteface获取算法策略的返回值。这里为了方便,我们使用简单的值传递示例,C++实现如下:
{
public:
virtual bool algorithmInterface(int x,int y)=0;
virtual ~Strategy(){}
};
class UpStrategy:public Strategy
{
public:
virtual bool algorithmInterface(int x,int y)
{
return x<y;
}
};
class DownStrategy:public Strategy
{
public:
virtual bool algorithmInterface(int x,int y)
{
return x>y;
}
};
class Context
{
Strategy*pStrategy;
public:
Context(Strategy*ps):pStrategy(ps){}
void sort()
{
if(pStrategy->algorithmInterface(1,2))
{
cout<<"1,2有序"<<endl;
}
else
{
cout<<"1,2反序"<<endl;
}
}
~Context()
{
delete pStrategy;
}
};
客户使用代码如下:
c1.sort();
Context c2(new DownStrategy());
c2.sort();
UpStrategy和DownStrategy决定比较的数据是升序还是降序,比较的结果通过统一接口algorithmInterface返回到调用者Context的sort函数中。使用时创建策略子类传递给Contex对象,而不用修改sort函数本身。如果要添加其他的比较方式,只需要添加一个策略子类就可以了。
来源:http://www.cnblogs.com/fanzhidongyzby/archive/2012/12/14/2818774.html