02: 策略模式

1. 案例:营业员根据客户所购买商品的单价和数量,根据不同活动向客户收费**

- 正常原价收费
- 八折收费
- 满300返100

2. 策略模式结构

- 抽象策略类(Stategy):声明算法的方法,抽象层的设计使上下文类可以无差别的调用不同的具体策略的方法

enum CashType
{
    NORMAL = 0,
    REBATE,
    RETURN
};

class CashSuper
{
public:
    virtual double AcceptCash(double dMoney) = 0;
};

- 具体策略类(Concrete Strategy):实现具体的算法

class CashNormal :
    public CashSuper
{
public:
    // 通过 CashSuper 继承
    double AcceptCash(double dMoney) override;
};

double CashNormal::AcceptCash(double dMoney)
{
    return dMoney;
}
class CashRebate :
    public CashSuper
{
public:
    explicit CashRebate(double dMoneyRebate);
    // 通过 CashSuper 继承
    double AcceptCash(double dMoney) override;
private:
    double m_dMoneyRebate;
};

CashRebate::CashRebate(double dMoneyRebate):
    m_dMoneyRebate(dMoneyRebate)
{
}

double CashRebate::AcceptCash(double dMoney)
{
    return dMoney * m_dMoneyRebate;
}
class CashReturn :
    public CashSuper
{
public:
    CashReturn(double dMoneyCondition, double dMoneyReturn);
    // 通过 CashSuper 继承
    double AcceptCash(double dMoney) override;
private:
    double m_dMoneyCondition;
    double m_dMoneyReturn;
};

CashReturn::CashReturn(double dMoneyCondition, double dMoneyReturn):
    m_dMoneyCondition(dMoneyCondition), m_dMoneyReturn(dMoneyReturn)
{
}

double CashReturn::AcceptCash(double dMoney)
{
    if (fabs(m_dMoneyCondition) < 1e-6)
        return dMoney;
    return dMoney - floor(dMoney / m_dMoneyCondition) * m_dMoneyReturn;
}

- 上下文类(Context):上下文类是使用算法的角色,可以在解决不同具体的问题时实例化不同的具体策略类对象

class CashSuper;
class Context
{
public:
    Context(CashType eCashType);
    double GetResult(double dMoney);
private:
    std::shared_ptr<CashSuper> m_spCashSuper;
};

Context::Context(CashType eCashType)
{
    switch (eCashType)
    {
    case NORMAL:
        m_spCashSuper = std::make_shared<CashNormal>();
        break;
    case REBATE:
        m_spCashSuper = std::make_shared<CashRebate>(0.8);
        break;
    case RETURN:
        m_spCashSuper = std::make_shared<CashReturn>(300.0, 100.0);
        break;
    default:
        m_spCashSuper = std::make_shared<CashNormal>();
        break;
    }
}

double Context::GetResult(double dMoney)
{
    return m_spCashSuper->AcceptCash(dMoney);
}

3. 用法

    std::shared_ptr<Context> spCashNormalContext = std::make_shared<Context>(CashType::NORMAL);
    std::shared_ptr<Context> spCashRebateContext = std::make_shared<Context>(CashType::REBATE);
    std::shared_ptr<Context> spCashReturnContext = std::make_shared<Context>(CashType::RETURN);
    std::cout << spCashNormalContext->GetResult(600) << std::endl;
    std::cout << spCashRebateContext->GetResult(600) << std::endl;
    std::cout << spCashReturnContext->GetResult(600) << std::endl;
posted @ 2024-09-16 09:59  博瑜图形  阅读(25)  评论(0)    收藏  举报