这里选择了策略模式,用于商场促销。
一、模式定义
策略模式作为一种软件设计模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。策略模式定义一系列的算法,将每一种算法封装起来并可以相互替换使用,策略模式让算法独立于使用它的客户应用而独立变化。 策略模式的决定权在用户,系统本身提供不同算法的实现,新增或者删除算法,对各种算法做封装。因此,策略模式多用在算法决策系统中,外部用户只需要决定用哪个算法即可。
二、模式分析
此处的具体场景如下:
促销商品的方式有以下几种: (1)打8折促销商品; (2)满1000元减200促销商品; (3)满200元,高于200的部分打8折促销商品。
商品促销中的策略分析 使用策略模式实现过程当中,需要满足以下几点内容:
(1)需要一个总体结构负责保存当前的具体策略,然后在具体的使用方法中调用具体策略实现相应的算法;
(2)可以在适当的时候改变当前策略;
(3)每一种条件分支作为一个具体策略算法单独实现
三、具体实现
1.关键代码
(1)付款金额计算的抽象类
class Cash { public: //计算应付金额 virtual double AcceptCash(double money) = 0; };
(2)具体策略类
//8折促销策略 class RebateStrategy : public Cash { private: double discount; public: RebateStrategy( double dis ) : discount(dis) { } virtual double AcceptCash(double money) { return money * discount; } };
//满1000减200促销策略 class ReduceStrategy : public Cash { private: double moneyLimit; double moneyMinus; public: ReduceStrategy( double limit, double minus ) : moneyLimit(limit), moneyMinus(minus) {} virtual double AcceptCash(double money) { double result = money; if( money > moneyLimit ) { result = money - 200; } return result; } };
//200以上部分打8折促销策略 class PromotionalStrategy : public Cash { private: double moneyCondition; double discount; public: PromotionalStrategy( double condition, double dis ) : moneyCondition(condition), discount(dis) {} virtual double AcceptCash(double money) { double result = money; if( money > moneyCondition ) { result = 200+(money-200)*discount; } return result; } };
(3)收费策略
class CashContext { private: Cash* cs; //声明付款金额的收费策略 public: //初始化时,传入具体的策略对象 CashContext(int type) { switch(type) { case 1: cs = new RebateStrategy(0.8); break; case 2: cs = new ReduceStrategy(1000,200); break; case 3: cs = new PromotionalStrategy(200, 0.8); break; default: exit(0); } } ~CashContext() { delete cs; } //得到现金计算结果 double GetResult( double money ) { return cs->AcceptCash(money); } };
(4)应用场景
int main() { double price; double number; int type; // 活动类型 cout<<"请输入单价: "; cin>>price; cout<<"请输入数量: "; cin>>number; cout<<"请选择促销活动:"<<endl <<"1 : 打8折"<<endl <<"2 : 满1000减200"<<endl <<"3 : 200以上部分打8折"<<endl; cin>>type; try { CashContext cashcontext(type); cout<<"总计:"<< price * number<<endl; cout<<"实收现金:"; cout<<cashcontext.GetResult( price * number )<<endl; } catch(exception& e) { cout<<e.what()<<endl; } return 0; }
四、实现分析
1.引入该设计模式后对系统架构和代码结构带来了哪些好处
(1) 策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码转移到父类里面,从而避免重复的代码;
(2) 策略模式提供了可以替换继承关系的办法。继承可以处理多种算法或行为。如果不是用策略模式,那么使用算法或行为的环境类就可能会有一些子类,每一个子类提供一个不同的算法或行为。但是,这样一来算法或行为的使用者就和算法或行为本身混在一起。决定使用哪一种算法或采取哪一种行为的逻辑就和算法或行为的逻辑混合在一起,从而不可能再独立演化。
(3)使用策略模式可以避免使用多重条件转移语句。多重转移语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重转移语句里面,比使用继承的办法还要原始和落后。
2.解释其中用到的多态机制
多态即接口的多种不同的实现方式,这里计算付款结果时使用了多态“AcceptCash(money)",父对象根据当前赋值给其子对象不同的运作方式从而选择了不同的执行操作。
3.说明模块抽象封装的方法
抽象:将不同促销方式的公有属性提取出来,这些促销的方式的公有属性即计算最终付款金额。
封装:将数据和对数据进行的操作封装在一个类中,数据被保存在内部,程序其他部分通过成员函数访问数据,即这里的discount和moneyCondition。
4.分析各个模块的内聚度和模块之间的耦合度;
内聚度:内聚度(Cohesion)是模块内部各成份(语句或语句段)之间的联系。显然,模块内部各成份联系越紧,即其内聚度越大,模块独立性就越强,系统越易理解和维护。具有良好内聚度的模块应能较好地满足信息局部化的原则,功能完整单一。这里每一个类封装性都很好,内聚度高。
耦合度:耦合度是从模块外部考察模块的独立性程度。它用来衡量多个模块间的相互联系。一般来说,耦合度应从以下三方面来考虑,即:耦合内容的数量,即模块间发生联系的数据和代码的多少,同这些数据和代码发生联系的模块的多少。这里模块之间联系很弱,耦合度低。
总体来说是,高内聚低耦合。
5.GitHub链接:https://github.com/Colinmeee/PromotionStrategy
原文:https://www.cnblogs.com/wendyyu/p/11972864.html