您的位置:首页 > 其它

设计模式之策略模式学习

2012-05-02 23:16 387 查看
策略模式:它定义了算法家族,分别封装起来,让他么之间可以互相替换。此模式让算法的变化,不会影响使用这些算法的客户。

在引出策略模式时,讨论了超市收银系统。可以将各种收费项目抽象成几种操作,比如正常收费、打折、返现、返积分。。。对打折来说,之所以可以这样进行抽象因为各种折扣之间存在着相互的联系,故将其抽象为一种。返现、返积分也类似。

算法本身是一种策略,这些算法可能随时被替换,这就是变化点,而封装变化点是面向对象一种很重要的思维方式。

策略模式是定义了一系列算法的方法,从概念上来看所有这些算法完成相同的工作,只是实现不同。它可以以相同的方式调用所有的算法,减少了各种算法类与使用它的算法类之间的耦合。

看代码:

//收费对象虚基类。

classSuperCashier { public: doubleprice; intnum; public: SuperCashier(doubleprice,intnum) { this->price=price; this->num=num; } virtualdoublegetTotalMoney()=0; };
//正常收费

classNormal:publicSuperCashier { public: doublediscount; public: Normal(doubleprice,intnum) :SuperCashier(price,num) { } virtualdoublegetTotalMoney() { returnprice*num; } };

//打折
classDiscount:publicSuperCashier
{
public:

doublediscount;
public:
Discount(doubleprice,intnum,doublediscount)
:SuperCashier(price,num)
{
this->discount=discount;
}
virtualdoublegetTotalMoney()
{
returnprice*num*discount;
}

};

//返点
classReturnPoint:publicSuperCashier
{
public:
doubleconditionMoney;
doublepoint;
public:
ReturnPoint(doubleprice,doublenum,doublecm,doublerp)
:SuperCashier(price,num),conditionMoney(cm),point(rp)
{

}
virtualdoublegetTotalMoney()
{
doubletotal=price*num;
if(total>=conditionMoney)
{
doublen=total/conditionMoney;
returnpoint*n;

}
return0;
}

};



//返现金
classReturnMoney:publicSuperCashier
{
public:
doubleconditionMoney;
doublereturnNum;
public:
ReturnMoney(doubleprice,doublenum,doublecm,doublereturnNum)
:SuperCashier(price,num),conditionMoney(cm)
{
this->returnNum=returnNum;
}
virtualdoublegetTotalMoney()
{
doubletotal=num*price;
if(total>=conditionMoney)
{
doublen=total/conditionMoney;
returntotal-n*returnNum;
}
}
};

/************************************************************************/
/*策略模式。*/
/***********************************************************************
classCashContext
{
public:
SuperCashier*sc;
public:
CashContext(SuperCashier*sc)
{
this->sc=sc;
}
doublegetResult()
{
returnsc->getTotalMoney();
}

};
//在客户端进行判断。intmain(intargc,char**argv)
{
doubleprice;
doublenum;
CashContext*cc;
while(1)
{
cout<<"1..正常收费。2..打折。3..返点4..返利"<<endl;
intch;

cin>>ch;getchar();
switch(ch)
{
case1:
{
cin>>price>>num;
cc=newCashContext(newNormal(price,num));

}
break;
case2:
{
doublediscount;
cin>>price>>num>>discount;
cc=newCashContext(newDiscount(price,num,discount));
}
break;
case3:
{
doubleconditionMoney;
doublereturnPoint;
cin>>price>>num>>conditionMoney>>returnPoint;
cc=newCashContext(newReturnPoint(price,num,conditionMoney,returnPoint));
}
break;
case4:
{
doubleconditionMoney;
doublereturnMoney;
cin>>price>>num>>conditionMoney>>returnMoney;
cc=newCashContext(newReturnMoney(price,num,conditionMoney,returnMoney));
}
break;
default:
break;
}
cout<<cc->getResult()<<endl;
deletecc;
}

return0;
}*/

/************************************************************************/
/*策略模式与简单工厂模式结合,即将在main中的switch循环移到CashContext类中*/
/************************************************************************/
classCashContext
{
public:
inttype;
doubleprice;
doublenum;
doublediscount;
doubleconditionMoney;
doubleret;
SuperCashier*sc;
public:
CashContext(intt,doubleprice,intnum,doublediscount)
:type(t)
{
this->price=price;
this->num=num;
this->discount=discount;

sc=NULL;
}
CashContext(intt,doubleprice,intnum)
:type(t)
{
this->price=price;
this->num=num;
sc=NULL;
}
CashContext(intt,doubleprice,intnum,doubleconditionMoney,doubleret)
:type(t)
{
this->price=price;
this->num=num;
this->conditionMoney=conditionMoney;
this->ret=ret;
sc=NULL;
}
doublegetResult()
{

switch(type)
{
case1://正常收费
{
sc=newNormal(price,num);
}
break;
case2://打折
{
sc=newDiscount(price,num,discount);
}
break;
case3://返点
{
sc=newReturnPoint(price,num,conditionMoney,ret);
}
break;
case4://返现
{
sc=newReturnPoint(price,num,conditionMoney,ret);
}
break;
default:
break;
}
returnsc->getTotalMoney();

}
};
intmain(intargc,char**argv)
{
CashContext*cc;
doubleprice,num,discount,conditionMoney,ret;

cin>>price>>num;
cc=newCashContext(1,price,num);
cout<<cc->getResult()<<endl;
deletecc;

cin>>price>>num>>discount;
cc=newCashContext(2,price,num,discount);
cout<<cc->getResult()<<endl;
deletecc;

cin>>price>>num>>conditionMoney>>ret;
cc=newCashContext(3,price,num,conditionMoney,ret);
cout<<cc->getResult()<<endl;
deletecc;

cin>>price>>num>>conditionMoney>>ret;
cc=newCashContext(4,price,num,conditionMoney,ret);
cout<<cc->getResult()<<endl;
deletecc;

return0;

}

此处觉得有不妥,一旦超市推出另外一些活动,CashContext类中用于switch判断的代码就要修改,程序需要重新编译。这在实际应用中是不可能的。第二章的最后提了一下使用映射可以解决这个问题。但不知映射为何物,拭目以待吧

注:此处实现的收费对象类,比书上的多实现了返点类。关于此类不知应该将其归为哪一部分,暂将其放入收费对象类中。但觉得不应该与收费对象类放在一起,应该有另外一个类处理返点。毕竟积分信息的管理对于大型超市来说也是很重要的一部分。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: