- 一件事情要做成,往往有多种方法。比如一个专业3个班级,每个班级都是30人,要计算整个专业的人数,对于这个问题,我们既可以用加法也可以用乘法完成。
- 策略模式针对的就是这种情况:一个问题多种解法(策略)。
模式定义
策略模式(Strategy Pattern):定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。策略模式中,决策者类(如下例的CashContext)可以通过设置来选择使用不同的策略,从而得到不同的结果。
实例:
商场中商品的收费方式,是与商场的销售策略相关的。商场可以原价销售,也可以为了打开销路,选择打折的方式,或者返现的方式。而商场的收费系统是已打包好的软件,并不可能为了一个新的打折折扣率,就重新编译软件,为此,我们只有往往先设计好可能会用到的销售策略,但是策略具体执行多少的折扣率,则可以根据商场的需求随时更改。
基于这样一种多种销售策略的模式,根据当前的销售策略,适当的选择结算方法,策略模式正好能够满足。
/*
策略模式
*/
#ifndef _STRATEGY_
#define _STRATEGY_
#define NULL 0
//抽象基类
class Cash //收费结算(计算最终收费)
{
public:
virtual double acceptMoney(double x) = 0;
};
//收费方式:原价
class CashNormal : public Cash
{
public:
virtual double acceptMoney(double x)
{
return x;
}
};
//收费方式:打折
class CashRebate :public Cash
{
private:
double Rebate = 1.0;//折扣
public:
CashRebate(double y)
{
this->Rebate = y;
}
virtual double acceptMoney(double x)
{
return x * Rebate;
}
};
//收费方式:返利
class CashReturn :public Cash
{
private:
double bound = 0.0;//打折下界
double moneyReturn = 0.0;//返利
public:
CashReturn(double _b, double _R)
{
this->bound = _b;
this->moneyReturn = _R;
}
virtual double acceptMoney(double x)
{
double res = x;
if (x >= bound)
res = x - (x / bound) * moneyReturn;
return res;
}
};
// 具体结算类
class CashContext
{
public:
// 设置收费方式
void setStrategy(Cash * _cs)
{
cs = _cs;
}
double GetResult(double money)
{
if (cs == nullptr)
{
return -1;
}
return cs->acceptMoney(money);
}
private:
Cash * cs = nullptr;
};
#endif //_STRATEGY_
测试代码:
int main()
{
Cash* func = new CashRebate(1.1);
CashContext * money = new CashContext();
money->setStrategy(func);
cout << money->GetResult(100) <<endl; //110
delete func;
func = new CashReturn(80,10);
money->setStrategy(func);
cout << money->GetResult(100) <<endl; //87.5
return 0;
}
小结
策略模式,适用于一个问题有多种解法的情况。所以,在工厂方法模式中给出的算术例子,其实也可以用策略模式来完成。