什么是策略模式?
策略模式是一种定义一系列算法的方法,定义了算法家族,分别封装起来,让他们可以相互转化,此模式可以让算法相互转化,且不会影响到算法用户。从概念上来看,所以的算法完成都是相同的工作,只是实现不同。它可以以相同方式调用所有的算法,减少了各种算法类与使用算法类的耦合。
我们用书里面的例子演示一下:假如超市的售货员给顾客结账时,她应该如何选择那种结算方式呢?
假如有:满100减20,满300减70,打5折等等。
我们想,如果用正常的逻辑语句应该怎么写:
if(money>=100){
money -=20;
}else if(money>=300){
money -=70;
}else{
money/=2;
}
当我们每加入一次结算方式,我们就需要加入一条if-else语句(或者switch语句)实现,然后进行大量的编译过程,浪费大量的人力物力。
既然学习了设计模式,我们就把这个问题系统化。
简单工厂模式实现
使用之前所学的 工厂模式实现.
先设计出来uml图.
这样代码就好实现了如下:
#include<iostream>
#include<cmath>
#include<string>
using namespace std;
class AbstractCashbuy{ //抽象基类
public:
virtual double accpetCash(double money) = 0;
};
class CashBuyNormal :public AbstractCashbuy{
public:
virtual double accpetCash(double money){
return money;
}
};
class CashBuyDiscount : public AbstractCashbuy{
private:
double discount;
public :
CashBuyDiscount(double num){
this->discount = num;
}
virtual double accpetCash(double money){
return money*discount;
}
};
class CashBuyReduct : public AbstractCashbuy{
private:
double full;
double reduct;
public :
CashBuyReduct (double num,double num1){
this->full = num;
this->reduct = num1;
}
virtual double accpetCash(double money){
return money-floor(money/full)*reduct;
}
};
class CashbuyFactory{
private:
AbstractCashbuy* CashMethod;
public :
//策略工厂模式
CashbuyFactory(string str,double discount,double sub=0){
if(str == "normal"){
this->CashMethod = new CashBuyNormal;
}
else if(str == "discount"){
this->CashMethod = new CashBuyDiscount(discount);
}
else if(str =="reduct"){
this->CashMethod = new CashBuyReduct(discount,sub);
}
}
double Getmoney(double money){
return CashMethod->accpetCash(money);
}
//工厂模式
AbstractCashbuy* CreateCashbuy(string str){
if(str == "normal"){
return new CashBuyNormal;
}
else if(str == "discount"){
return new CashBuyDiscount(0.5);
}
else if(str == "reduct"){
return new CashBuyReduct(500,80);
}
}
};
int main(){
string str,str1,str2;
str = "normal";
str1 = "discount";
str2 = "reduct";
CashbuyFactory* a= new CashbuyFactory(str2,500,40);
cout<<a->Getmoney(500)<<endl;
// AbstractCashbuy* b = a->CreateCashbuy(str);
// cout<<b->accpetCash(500);
}
策略模式(Strategy)
策略模式的uml图:
代码如下:(与工厂模式结合)
#include<iostream>
#include<cmath>
#include<string>
using namespace std;
class AbstractCashbuy{ //抽象基类
public:
virtual double accpetCash(double money) = 0;
};
class CashBuyNormal :public AbstractCashbuy{
public:
virtual double accpetCash(double money){
return money;
}
};
class CashBuyDiscount : public AbstractCashbuy{
private:
double discount;
public :
CashBuyDiscount(double num){
this->discount = num;
}
virtual double accpetCash(double money){
return money*discount;
}
};
class CashBuyReduct : public AbstractCashbuy{
private:
double full;
double reduct;
public :
CashBuyReduct (double num,double num1){
this->full = num;
this->reduct = num1;
}
virtual double accpetCash(double money){
return money-floor(money/full)*reduct;
}
};
class CashbuyFactory{
private:
AbstractCashbuy* CashMethod;
public :
//策略工厂模式
CashbuyFactory(string str,double discount,double sub=0){
if(str == "normal"){
this->CashMethod = new CashBuyNormal;
}
else if(str == "discount"){
this->CashMethod = new CashBuyDiscount(discount);
}
else if(str =="reduct"){
this->CashMethod = new CashBuyReduct(discount,sub);
}
}
double Getmoney(double money){
return CashMethod->accpetCash(money);
}
}
int main(){
string str,str1,str2;
str = "normal";
str1 = "discount";
str2 = "reduct";
CashbuyFactory* a= new CashbuyFactory(str2,500,40);
cout<<a->Getmoney(500)<<endl; //输出460
}
策略模式的优势
策略模式的Strategy类层次为Context定义了一系列的可供重用的算法。继承有助于析取出这些算法的公共功能,简化了单元测试。并且发现,在策略模式中,我们只需要记住一个CashbuyFactory 类即可,而在工厂模式中,我们需要记住两个类 CashbuyFactory 和 AbstractCashbuy。所有策略模式简化了类的数量。