C++ 設(shè)計(jì)模式 —— 21.策略模式

  • 策略模式:一種行為型設(shè)計(jì)模式

  • 應(yīng)用場(chǎng)景:
    在GOF的《設(shè)計(jì)模式:可復(fù)用面向?qū)ο筌浖幕A(chǔ)》中是這樣定義的:將一系列的算法一個(gè)個(gè)封裝起來,并且使它們可相互替換。策略模式使得算法可獨(dú)立于使用它的客戶而變化。
    對(duì)于同一流程中不同的需求,對(duì)數(shù)據(jù)的處理算法可能會(huì)變更,所以將處理數(shù)據(jù)的算法單獨(dú)抽離出去,形成一系列算法類,可以相互替換。

  • 舉例:
    《大話設(shè)計(jì)模式》中舉了一個(gè)很好的例子。
    商場(chǎng)經(jīng)常會(huì)推出不同的優(yōu)惠活動(dòng),對(duì)于結(jié)賬流程來說,不同的優(yōu)惠活動(dòng)會(huì)使用不同的算法處理賬單總額。
    所以抽離出一個(gè)算法的基類,提供統(tǒng)一的用于計(jì)算折后價(jià)的接口,然后所有的算法都在派生類中實(shí)現(xiàn)各自的方法。
    切換商場(chǎng)類中的算法指針?biāo)赶虻乃惴?,即可切換調(diào)用的算法。

  • 實(shí)現(xiàn)方式:
    所有算法類派生自同一基類,實(shí)現(xiàn)統(tǒng)一的計(jì)算接口。
    商場(chǎng)類中使用成員指針指向具體的算法類,結(jié)賬時(shí)通過該指針調(diào)用算法。


以下是策略模式的簡(jiǎn)單代碼實(shí)現(xiàn)
#include <iostream>
using namespace std;

//策略基類
class Strategy
{
public:
    virtual float Calculate(float fTotal) = 0;
};

//策略A,打8折
class StrategyA:public Strategy
{
public:
    virtual float Calculate(float fTotal)
    {
        printf("優(yōu)惠活動(dòng),全部8折\n");
        return fTotal * 0.8;
    }
};

//策略B,打7折
class StrategyB:public Strategy
{
public:
    virtual float Calculate(float fTotal)
    {
        printf("優(yōu)惠活動(dòng),全部7折\n");
        return fTotal * 0.7;
    }
};

//策略C,滿300減100
class StrategyC:public Strategy
{
public:
    virtual float Calculate(float fTotal)
    {
        printf("優(yōu)惠活動(dòng),滿300減100\n");
        float fFinal = fTotal - static_cast<int>(fTotal/300) * 100;
        return fFinal;
    }
};

//商場(chǎng)類
class Shop
{
public:
    Shop(Strategy* pStrategy = NULL):m_pStrategy(pStrategy){}
    ~Shop()
    {
        if(m_pStrategy)
        {
            delete m_pStrategy;
            m_pStrategy = NULL;
        }
    }

    //設(shè)置商場(chǎng)策略
    void SetStrategy(Strategy* pStrategy)
    {
        if(m_pStrategy)
        {
            delete m_pStrategy;
        }
        m_pStrategy = pStrategy;
    }

    //調(diào)用策略類的計(jì)算方法計(jì)算折后價(jià)
    void CalculatePay(float fTotal)
    {
        if(m_pStrategy)
        {
            float fFinal = m_pStrategy->Calculate(fTotal);
            printf("原價(jià):%.2f元, 折后:%.2f元\n", fTotal, fFinal);
        }
        else
        {
            printf("無活動(dòng),總價(jià):%.2f元\n", fTotal);
        }
    }

private:
    Strategy* m_pStrategy;
};
主函數(shù)中的使用
int main()
{
    Shop oShop;
    oShop.CalculatePay(400);

    oShop.SetStrategy(new StrategyA());
    oShop.CalculatePay(400);

    oShop.SetStrategy(new StrategyB());
    oShop.CalculatePay(400);

    oShop.SetStrategy(new StrategyC());
    oShop.CalculatePay(400);

    return 0;
}
控制臺(tái)輸出結(jié)果
無活動(dòng),總價(jià):400.00元
優(yōu)惠活動(dòng),全部8折
原價(jià):400.00元, 折后:320.00元
優(yōu)惠活動(dòng),全部7折
原價(jià):400.00元, 折后:280.00元
優(yōu)惠活動(dòng),滿300減100
原價(jià):400.00元, 折后:300.00元

如有錯(cuò)誤,歡迎指正

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容