策略模式
#include <string> /* 策略模式:定义一系列算法的方法,从概念上说所有这些算法完成相同的工作,只是实现不同,他用相同的方式调用所有的算法,减少了各种算法类和使用算法类之间的耦合 策略模式的strategy类层次为context定义了一系列的可供重用的算法和行为,继承有助于析取出这些算法的公共部分 刚开始写代码时我们喜欢使用switch() {...}结构 当不同的行为堆砌在同一个类中时,就很难避免使用条件语句来选择合适的行为,将这些行为封装在一个个独立的strategy类中,可以在这些行为的类中消除条件语句 */ /// 抽象strategy类,定义所有支持算法的公共接口 class CashSuper { public: virtual float AcceptCash(float fMoney) = 0; }; /// 正常收费(具体策略) class CashNormal : public CashSuper { public: virtual float AcceptCash(float fMoney) { return fMoney; } }; /// 打折收费(具体策略) class CashRebate : public CashSuper { private: float m_fDiscount; public: CashRebate(float fDiscount):m_fDiscount(fDiscount){} virtual float AcceptCash(float fMoney) { return fMoney * m_fDiscount; } }; /// 返利收费(具体策略) class CashReturn : public CashSuper { private: float m_fMoneyCondition; float m_fMoneyReturn; public: CashReturn(float fMoneyCondition, float fMoneyReturn):m_fMoneyCondition(fMoneyCondition), m_fMoneyReturn(fMoneyReturn){} virtual float AcceptCash(float fMoney) { if (fMoney > m_fMoneyCondition) { return fMoney - fMoney / m_fMoneyCondition * m_fMoneyReturn; } return fMoney; } }; /// concretestrategy配置,维护抽象strategy指针 /// 加入简单工厂 /// 将实例化具体策略过程由客户端转移到Context中,简单工厂的应用 class CashContext { private: CashSuper* m_pCashSuper; public: CashContext(CashSuper* pCashSuper):m_pCashSuper(pCashSuper){} //参数不是具体收费策略对象,而是类型表示收费类型 CashContext(int nCurSel) { switch (nCurSel) { case 0: m_pCashSuper = new CashNormal; break; case 1: m_pCashSuper = new CashReturn(300, 100); break; case 2: m_pCashSuper = new CashRebate(0.8f); break; default: break; } } float GetResult(float fMoney) { return m_pCashSuper->AcceptCash(fMoney); } }; class CashFactory { public: static CashSuper* CreateCashAccept(int nType) { switch(nType) { case 0://正常收费 return new CashNormal; case 1://返利收费 return new CashReturn(300, 100); case 2://打折收费 return new CashRebate(0.8f); } return nullptr; } };
//使用者只需要知道CashContext即可,降低耦合度 CashContext* pCashContext = new CashContext(m_comComputeWay.GetCurSel()); float fPerTotalPrice = 0; //调用GetResult方法使得具体的收费算法彻底与客户端分离 fPerTotalPrice = pCashContext->GetResult(m_fPerPrice * m_nNum); char szBuf[256] = {0}; sprintf_s(szBuf, 256, "单价:%f 数量:%d 合计:%f", m_fPerPrice, m_nNum, fPerTotalPrice); m_ListPrice.AddString(szBuf); m_fTotalPrice += fPerTotalPrice;