c++ 实现策略模式

来源:互联网 发布:php滚动加载 编辑:程序博客网 时间:2024/06/05 03:07

策略模式(Strategy):它定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。

上面是《大话设计模式》中给出的定义,感觉这个概念给的不好,看了之后不能完全清晰明白该模式(可能自己水平太水的原因吧)。在《effective c++》中指出,策略模式是virtual 函数的替换方法。仔细想想也差不多。如果想在不同的类中实现不同的算法,那么在基类中定义一个virtual函数,派生类给出不同的实现即可。这里出现一个问题,如果要实现的算法太多(算法参数、返回值等不同),那么需要在基类中都进行virtual声明,在具体的类中给出具体函数的实现。那么每个派生类都需要继承那么多virtual 函数(而且多数没用),派生类好臃肿啊。有人给出派生类减肥法,工厂模式,其实就是每个算法给出一个实现类外加多态的使用;别的方法,那就是每个算法实现一个类,把这个类传入到具体的过程类中,让算法类作为过程类的一个属性,可以根据要求进行设置,当然这个算法跟工厂模式有些相似处。(后面有两者关系图)

先描述一下应用场景吧,设计商场收费软件,要求能够满足,不同的打折要求、不同的满几百送几百的返利要求。比如:店庆打8折,国庆节满300送100;

下面看一下,工厂模式和策略模式关系图,看一下他们之间的差别:

工厂模式:


策略模式:



下面看一下传统的策略模式的实现代码:

#include<iostream>#include<string>using namespace std;class CashSuper{public:virtual double acceptCash(double money) = 0;};class CashNormal : public CashSuper{public :double acceptCash(double money){return money;}};class CashRebate : public CashSuper{public:CashRebate(double d = 1) : moneyRebate(d){}double acceptCash(double money);private:double moneyRebate; };double CashRebate::acceptCash(double money){return money * moneyRebate;}class CashReturn : public CashSuper{public:CashReturn(double mc = 0.0, double mr = 0.0) : moneyCondition(mc), moneyReturn(mr){}double acceptCash(double money);private:double moneyCondition;double moneyReturn;};double CashReturn::acceptCash(double money){double result = money;if (money > moneyCondition)result = money - (int)(money / moneyCondition)* moneyReturn;return result;}class CashContext{public :CashContext(CashSuper *cashuper) : cs(cashuper){}double GetResult(double money);private:CashSuper *cs;};double CashContext::GetResult(double money){return cs->acceptCash(money);}

上面的是传统策略模式的实现代码,但是只是个框架,很好看,不中用;没有具体环境执行。

下面是策略模式和工厂模式结合的代码,情景如上所述:其中1代表:正常模式收费;     2代表:满300送100;   3代表:打8折。

将上面的CashContext替换成ConcreteCashContext就可以直接运行了。

class ConcreteCashContext{public:ConcreteCashContext(int type);double GetResult(double money);private:CashSuper *cs;};double ConcreteCashContext::GetResult(double money){return cs->acceptCash(money);}ConcreteCashContext::ConcreteCashContext(int type){switch(type){case 1:cs = new CashNormal();break;case 2:cs = new CashReturn(300,100);break;case 3:cs = new CashRebate(0.8);break;default:cout << " cant not recognize the type " << endl;}}int main(int argc, char **argv){ConcreteCashContext *ccc = new ConcreteCashContext(2);double money = 850.45;cout << " The moeny is : " << money << endl;cout << "you have to pay : " << ccc->GetResult(money) << endl;system("pause");return 0;}


参考:

1、《大话设计模式》

2、《effective c++》