要求:收银系统
| 增加打折模式:
|
如果增加满减活动?增加积分兑换呢? |
先尝试简单工厂实现: 最初想法:
但是 打折、满减实际上他们具有不同的计算方式,传入的参数也不同,每有一种新的促销都要改代码,即使是同类满减促销。比如之前写了满100减10,但是后来有满300减40,满500减60都要重新写界面、工厂和子类。 从这可以看出简单工厂模式的弊端是只适用于参数相同的模式。(个人理解) 所以有了: 策略模式: 它定义了算法家族,分别封装起来,让他们之间可以互相转换,此模式让算法的变化,不会影响到使用算法的客户。 一言蔽之:封装了算法。 可是有新的促销依然要改界面、cashContext和子类 |
| //子类 #pragma once #include "cashSuper.h" class cashNormal:public cashSuper { public: double acceptCash(double originMoney) { return originMoney; } protected: private: }; class cashRebate :public cashSuper { public: cashRebate(double rebate) { _rebate = rebate; } double acceptCash(double originMoney) { return originMoney*_rebate; } protected: private: double _rebate; }; class cashReturn :public cashSuper { public: cashReturn(double conditionMoney, double returnMoney) { _conditionMoney = conditionMoney; _returnMoney = returnMoney; } double acceptCash(double originMoney) { double ret = originMoney; ret -= ((originMoney / _conditionMoney)*_returnMoney); return ret; } protected: private: double _conditionMoney, _returnMoney; }; | |||
于是:把界面的职责简化,托付给Context的职责。就连选择的策略也给context,而不要留在前端。 策略与简单工厂模式的结合: | 修改后的context: enum option { NORMAL, REBATE, RETURN }; class cashContext { public: cashContext(option op) { //修改部分 Switch (op) { case NORMAL CashNormal cs0 = new CashNormal(); cs = cs0; break; case REBATE: CashNormal cs1= new cashContext(new cashRebate(0.8)); cs = cs1; break; case RETURN: CashNormal cs2 = new cashContext(new cashReturn(300, 100)); cs = cs2; break; } } double getResult(double money) { return cs->acceptCash(money); } private: cashSuper *cs; }; | //修改后的界面 int main() { while (1) { double total = 0; int op; double money; cout << "请输入总价、打折方式"<<endl; cin >> money>> op ; //修改后只需交给context判断就可以了 cashContext *cc = new CashContest((option)op); total = cc->getResult(money); cout << total<<endl; } return 0; } |