#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;