策略模式

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

 

posted @ 2015-04-08 21:23  zzyoucan  阅读(226)  评论(0编辑  收藏  举报