设计模式(2)--策略模式
2016-11-01 01:17 sylar_liang 阅读(200) 评论(0) 编辑 收藏 举报//2.策略模式 //ver1 //现金收费抽象类 class CashSuper { public: CashSuper(){} ~CashSuper(){} public: virtual double acceptCash(double money) { return money; } }; //正常收费类 class CashNormal : public CashSuper { public: CashNormal(){} ~CashNormal(){} public: virtual double acceptCash(double money) { return money; } }; //打折收费类 class CashRebate : public CashSuper { private: double _moneyRebate; public: CashRebate(double moneyRebate) { _moneyRebate = moneyRebate; } virtual double acceptCash(double money) { return money * _moneyRebate; } }; //返利收费类 class CashReturn : public CashSuper { private: double _moneyCondition; double _moneyReturn; public: CashReturn(double moneyCondition, double moneyReturn) { _moneyCondition = moneyCondition; _moneyReturn = moneyReturn; } virtual double acceptCash(double money) { double result = money; if (money >= _moneyCondition) { money = money - floor(money/_moneyCondition) * _moneyReturn; //floor 向下取整; ceil 向上取整 } return money; } }; enum eCashType { eNormal = 1, eRebate = 2, eReturn = 3 }; //现金收费工厂类 class CashFactory { public: static CashSuper CreateCashAccept(eCashType eType) { CashSuper * cs = NULL; switch(eType) { case eNormal: cs = new CashNormal(); break; case eRebate: cs = new CashRebate(0.8); break; case eReturn: cs =new CashReturn(300, 100); break; default: break; } return *cs; } }; void main1() { double total = 0.0; CashSuper csuper = CashFactory::CreateCashAccept(eRebate); total = csuper.acceptCash(350); //这里不方便在于,没法控制多少折; 参数没法传入; //解决:这里的处理是在定义枚举时分别定义,比如定八折 eRebate8 ,5折 eRebate5; 增加对应 case 语句; //缺点: 工厂包含了所有的收费方式,每增加一种或者修改一种收费方式,都需要更改工厂内容; }
策略模式: 定义算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到算法的客户.
//2.策略模式 //抽象算法类 class Strategy { public: virtual void AlgorithmInterface() = 0; }; //具体算法A class ConcreteStrategyA : public Strategy { public: virtual void AlgorithmInterface() { //算法A } }; //具体算法B class ConcreteStrategyB : public Strategy { public: virtual void AlgorithmInterface() { //算法B } }; //上下文; 用于管理 Strategy class Context { private: Strategy * _strategy; public: Context(Strategy * strategy) { _strategy = strategy; } //上下文接口 void ContextInterface() { _strategy->AlgorithmInterface(); } }; void main21() { Context *pContext = new Context(new ConcreteStrategyA()); pContext->ContextInterface(); pContext = new Context(new ConcreteStrategyB()); pContext->ContextInterface(); } //2.策略模式 //ver2 //现金收费抽象类 class CashSuper { public: CashSuper(){} ~CashSuper(){} public: virtual double acceptCash(double money) { return money; } }; //正常收费类 class CashNormal : public CashSuper { public: CashNormal(){} ~CashNormal(){} public: virtual double acceptCash(double money) { return money; } }; //打折收费类 class CashRebate : public CashSuper { private: double _moneyRebate; public: CashRebate(double moneyRebate) { _moneyRebate = moneyRebate; } virtual double acceptCash(double money) { return money * _moneyRebate; } }; //返利收费类 class CashReturn : public CashSuper { private: double _moneyCondition; double _moneyReturn; public: CashReturn(double moneyCondition, double moneyReturn) { _moneyCondition = moneyCondition; _moneyReturn = moneyReturn; } virtual double acceptCash(double money) { double result = money; if (money >= _moneyCondition) { money = money - floor(money/_moneyCondition) * _moneyReturn; //floor 向下取整; ceil 向上取整 } return money; } }; enum eCashType { eNormal = 1, eRebate = 2, eReturn = 3 }; class CashContext { private: CashSuper _csuper; public: CashContext(CashSuper cs) { _csuper = cs; } double GetResult(double money) { return _csuper.acceptCash(money); } }; //客户端调用 void main22() { CashContext *pcc = NULL; CashSuper *pcs = NULL; eCashType eType = eRebate; switch(eType) { case eNormal: pcs = new CashNormal(); *pcc = CashContext(*pcs); break; case eRebate: pcs = new CashRebate(0.8); *pcc = CashContext(*pcs); case eReturn: pcs = new CashReturn(300, 100); *pcc = CashContext(*pcs); default: break; } double money = 350; double result = pcc->GetResult(money); //缺点: 判断过程放在了客户端,暴露了太多的细节; }
//3.策略模式 //ver3 //跟前面的ver2一致,只修改main和CashContext类; class CashContext { private: CashSuper * pcs; public: CashContext(eCashType eType) { switch(eType) { case eNormal: pcs = new CashNormal(); break; case eRebate: pcs = new CashRebate(0.8); break; case eReturn: pcs = new CashReturn(300, 100); break; default: break; } } double GetResult(double money) { return pcs->acceptCash(money); } }; void main31() { CashContext *pcs = new CashContext(eRebate); double total = pcs->GetResult(350); //对比ver2,简单工厂模式客户端调用需要知道 CashSuper 和 CashFactory 类; //ver3, 简单工厂+策略模式,客户端只需要知道 CashContext 类: }
//策略模式的Strategy类为Context定义了一系列的可供重用的算法或行为。继承有助于取出这些算法中的公共功能。 //策略模式的优点是简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。
//另一种更好的模式可能是 反射模式。