商场促销 大话设计模式2-策略模式

大话设计模式2-策略模式
1.需求:商场促销
商场有不同的促销情况,可以打折、满减以及不促销
2.简单工厂实现
简单工厂实现可以①设计一个收费抽象类,交给子类去重写
#pragma onceclass cashSuper {public :virtual double acceptCash(double money){return money;}};
②再定义正常收费、满减、打折三个子类 。
正常收费
#pragma once#include"cashSuper.h"class cashNomal :public cashSuper {public:double acceptCash(double money){return money;}};
打折
#pragma once#include"cashSuper.h"class cashRebate :public cashSuper {public:cashRebate(double bate = 1):rebate(bate){}double acceptCash(double money){return money*rebate;}private:double rebate;};
满减
构造时需要两个参数分别是满减条件以及满减金额
#pragma once#include"cashSuper.h"class cashReturn :public cashSuper {private:double moneycond;double moneyret;public:cashReturn(double cond,double ret):moneycond(cond),moneyret(ret){}double acceptCash(double money){double res = money;if (money > moneycond)res = money - int((money / moneycond))* moneyret;return res;}};
③之后是工厂类,用来实例化合适的对象
#pragma once#include"cashNormal.h"#include"cashRebate.h"#include"cashReturn.h"#include"cashSuper.h"using namespace std;enum typeset{nomal,rebate,ret};class moneyFactory {public:cashSuper* createCash(typeset type) {cashSuper* cs = nullptr;switch (type){case nomal:cs = new cashNomal();break;case rebate:cs = new cashRebate(0.8);break;case ret:cs = new cashReturn(300,100);break;}return cs;}};
④main函数
#include"moneyFactory.h"#includeint main(){double res;cashSuper* su;moneyFactory factory;su = factory.createCash(nomal);res = su->acceptCash(600);cout << res << endl;su = factory.createCash(rebate);res = su->acceptCash(600);cout << res << endl;su = factory.createCash(ret);res = su->acceptCash(600);cout << res << endl;return 0;}
输入为600,在正常、打八折、满300减100情况下输出:

商场促销  大话设计模式2-策略模式

文章插图
3.策略模式
策略模式定义一系列算法,把它们一个个封装起来,并且使它们可互相替换(变化) 。该模式使得算法可独立于使用它的客户程序(稳定)而变化(扩展,子类化) 。
说白了就是封装各个促销方法,定义一个支持所有算法的接口这一步我们已经完成了,其次再通过一个类维护指针 。
两个作用:构造指针,根据具体的方法调用类算法完成多态,也就是说提供了接口 。让子类中的方法与客户进行隔离,客户只知道 。
#pragma once#include"cashSuper.h"class cashContext {public:cashContext(cashSuper *super): su(super){}double getRes(double money) {return su->acceptCash(money);}private:cashSuper* su;};
正常收费、满减、打折三个子类不变 。
正常收费
#pragma once#include"cashSuper.h"class cashNomal :public cashSuper {public:double acceptCash(double money){return money;}};
打折
#pragma once#include"cashSuper.h"class cashRebate :public cashSuper {public:cashRebate(double bate = 1):rebate(bate){}double acceptCash(double money){return money*rebate;}private:double rebate;};
满减
构造时需要两个参数分别是满减条件以及满减金额
#pragma once#include"cashSuper.h"class cashReturn :public cashSuper {private:double moneycond;double moneyret;public:cashReturn(double cond,double ret):moneycond(cond),moneyret(ret){}double acceptCash(double money){double res = money;if (money > moneycond)res = money - int((money / moneycond))* moneyret;return res;}};
#pragma onceclass cashSuper {public :virtual double acceptCash(double money){return money;}};
main函数实现
#include"cashContext.h"#include"cashNormal.h"#include"cashRebate.h"#include"cashReturn.h"#include"cashSuper.h"#includeusing namespace std;enum typeset { nomal, rebate, ret };int main(){typeset type = ret;cashContext* cc = nullptr;switch (type){case nomal:cc = new cashContext(new cashNomal());break;case rebate:cc = new cashContext(new cashRebate(0.8));break;case ret:cc = new cashContext(new cashReturn(300, 100));break;}double res = cc->getRes(600);cout << res;return 0;}
商场促销  大话设计模式2-策略模式

文章插图
4.策略模式与简单工厂的结合
我们先分析工厂模式与策略模式的缺点 。
如下图工厂模式中,我们需要工厂类和现金消费类两方协助才能够完成促销计算,增加了接口,维护较复杂 。
而策略模式虽然只需要一个上下文接口,但是在main函数也就是客户端中判断使用哪个算法,实现上也不好 。我们想把判断过程封装起来,这时我们需要工厂来封装,接口过多的问题我们需要策略模式解决,所以需要结合两种模式 。
由于我们客户希望只知道,所以要把工厂类搬到中,或者说由来实例合适的对象
以前的工厂类如下:
#include"cashReturn.h"#include"cashSuper.h"using namespace std;enum typeset{nomal,rebate,ret};class moneyFactory {public:cashSuper* createCash(typeset type) {cashSuper* cs = nullptr;switch (type){case nomal:cs = new cashNomal();break;case rebate:cs = new cashRebate(0.8);break;case ret:cs = new cashReturn(300,100);break;}return cs;}};
以前的类如下
#pragma once#include"cashSuper.h"class cashContext {public:cashContext(cashSuper *super): su(super){}double getRes(double money) {return su->acceptCash(money);}private:cashSuper* su;};
合并,依旧维护抽象计算的指针,此外还负责实例化具体策略 。
#pragma once#include"cashSuper.h"#include"cashNormal.h"#include"cashRebate.h"#include"cashReturn.h"enum typeset { nomal, rebate, ret };class cashContext {public:cashContext(typeset type){switch (type){case nomal:cs = new cashNomal();break;case rebate:cs = new cashRebate(0.8);break;case ret:cs = new cashReturn(300, 100);break;}}double getRes(double money) {return cs->acceptCash(money);}private:cashSuper* cs;};
其余类和三个子类不变
main函数如下
#include"cashContext.h"#includeusing namespace std;int main(){typeset s = ret;//满减cashContext* cc = new cashContext(s); double res = cc->getRes(600);cout << res;return 0;}
可以看出客户只认识,通过传入的策略多态实现促销计算 。
5.反思
【商场促销大话设计模式2-策略模式】策略模式可以将一系列算法封装起来,以相同的方式调用所有算法,减少了接口、每个算法也都有自己的类,可以单独进行调试 。