策略模式是定义一种一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。
结构图:
下面是根据上一篇简单工厂模式中的例子使用了策略模式后的代码:
#include <iostream>
using namespace std;
class Operation //定义一个算法类(作为基类)
{
private:
double NumberA ; //操作数 NumberA
double NumberB ; //操作数 NumberB
public:
void SetNumberA(double A){ NumberA = A ;} //给操作数A赋值
void SetNumberB(double B){ NumberB = B ;} //给操作数B赋值
double GetNumberA(){ return NumberA ;} //获取操作数A的值
double GetNumberB(){ return NumberB ;} //获取操作数B的值
virtual double GetResult() //虚函数GetResult() 利用多态实现派生类的GetResult()函数
{
double dblresult ;
return dblresult ;
}
};
class OperationAdd : public Operation //加法算法类
{
double GetResult()
{
double dblresult ;
double NumberA ;
double NumberB ;
NumberA = this->GetNumberA() ;
NumberB = this->GetNumberB() ;
dblresult = NumberA + NumberB ;
return dblresult ;
}
};
class OperationSUB : public Operation //减法算法类
{
double GetResult()
{
double dblresult ;
double NumberA ;
double NumberB ;
NumberA = this->GetNumberA() ;
NumberB = this->GetNumberB() ;
dblresult = NumberA - NumberB ;
return dblresult ;
}
};
class OperationMUL : public Operation //乘法算法类
{
double GetResult()
{
double dblresult ;
double NumberA ;
double NumberB ;
NumberA = this->GetNumberA() ;
NumberB = this->GetNumberB() ;
dblresult = NumberA * NumberB ;
return dblresult ;
}
};
class OperationDIV : public Operation //除法算法类
{
double GetResult()
{
double dblresult ;
double NumberA ;
double NumberB ;
NumberA = this->GetNumberA() ;
NumberB = this->GetNumberB() ;
try
{
if(NumberB == 0)
{
throw"对不起,除数不能为为0 !" ;
}
else
{
dblresult = NumberA / NumberB ;
return dblresult ;
}
}
catch (const char * message)
{
cout<<message<<endl ;
}
}
};
class OperationContext
{
private:
Operation * pOperation ; //声明一个算法类的指针
public:
OperationContext(char my_operate,double dblNumA,double dblNumB) //将运算符和操作数传入OperationContext的构造函数中
{
switch(my_operate)
{
case '+' :
{
pOperation = new OperationAdd ;
break;
}
case '-' :
{
pOperation = new OperationSUB ;
break;
}
case '*' :
{
pOperation = new OperationMUL ;
break;
}
case '/' :
{
pOperation = new OperationDIV ;
break;
}
}
pOperation->SetNumberA(dblNumA) ; //设置算法类中的操作数值
pOperation->SetNumberA(dblNumB) ;
}
double Getresult()
{
return pOperation->GetResult();
}
};
int main()
{
double NumberA,NumberB ;
char btoperate ;
try
{
cout<<"请输入数字A :";
cin>>NumberA ;
cout<<"请输入运算符(+、-、*、/) :";
cin>>btoperate ;
cout<<"请输入数字B :";
cin>>NumberB ;
OperationContext ObjOpeCon(btoperate,NumberA,NumberB) ;
cout<<"计算结果为:"<<ObjOpeCon.Getresult()<<endl ;
}
catch (exception &e)
{
cout<<"对不起,您的输入有误! "<<endl ;
}
return 0 ;
}
结合上述代码,策略模式的Operation类层次为
OperationContext定义了一系列的可供重用的算法或行为,继承有助于析取出这些算法类的公共功能,也就是代码中GetResult()。另外一个策略模式的优点是简化了单元测试,因为每个算法都自己的类,可以通过自己的接口单独测试。在这里策略模式是用来封装算法的,但在实践中,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑策略模式处理这种变化的可能性。