設計模式 -- 策略模式Strategy

策略模式:定義了算法家族,分別封裝起來,讓它們之間可以互相替換,此模式讓算法的變化,不會影響到使用算法的客戶。


組成:

  • 抽象策略角色Strategy:策略類,定義了所有支持的算法的公共接口

  • 具體策略角色ConcreteStrategyA : Strategy :繼承自Strategy,封裝了具體的算法或行爲,可能有很多。

  • 環境角色或者上下文角色,持有一個對Strategy對象的引用,給客戶端調用的。


應用場景:eg商場促銷;遊戲中不同狀態下人物的技能

  • 多個類只在表現行爲不同,在運行時候動態選擇不同的行爲

  • 不同的情況下使用不同的策略(算法),策略很可能在未來用其他方式實現

  • 對客戶端隱藏算法具體細節,彼此完全獨立


優點:

1. 避免代碼的重複:把公有的代碼放在父類裏

2. 繼承使得動態改變算法或邏輯變得可能

3. 避免多重條件轉移語句


缺點:

客戶端必須知道所有的策略類

每個具體策略都對應一個類,這時可以考慮下共享的辦法


一個例子:商場打折

結構圖如下


#include <iostream>
#include <cmath>
#include <map>
 
using namespace std;
 
//抽象算法類 : 現金收費
class CashSuper {
public:
    virtual double acceptCash(double money) = 0;
};
 
//具體算法A:正常收費
class CashNormal : public CashSuper {
public:
    double acceptCash(double money)
    {
        return money;
    }
};
 
//具體算法B:打折收費
class CashRebate : public CashSuper {
public:
    CashRebate(double _moneyRebate)
        : moneyRebat(_moneyRebate)
    {
    }
    double acceptCash(double money)
    {
        return money * moneyRebat;
    }
private:
    double moneyRebat;
};
 
//具體算法A:返利收費,滿?反?
class CashReturn : public CashSuper {
public:
    CashReturn(double _moneyCondition = 0.0, double _moneyReturn = 0.0)
        : moneyCondition(_moneyCondition), moneyReturn(_moneyReturn)
    {
    }
    double acceptCash(double money)
    {
        double result = money;
        if(money > moneyCondition)
        {
            result = money - floor(money/moneyCondition) * moneyReturn;
        }
        return result;
    }
private:
    double moneyCondition;
    double moneyReturn;
};
 
//上下文Context,與簡單工廠模式結合後的產物
class CashContext {
private:
    CashSuper *cs = NULL;
public:
    CashContext(string type)
    {
        if(type == "正常收費") {
            cs = new CashNormal();
        } else if(type == "滿300返100") {
            cs = new CashReturn(300, 100);
        } else if(type == "打8折") {
            cs = new CashRebate(0.8);
        }
    }
 
    double getResult(double money)
    {
        return cs->acceptCash(money);
    }
};
 
int main() {
    double total = 0.0;
    CashContext *csuper = new CashContext("正常收費");
    total = total + csuper->getResult(5.0 * 4); //單價5.0 * 4個
    cout << "單項價格:" << csuper->getResult(5.0 * 4) << endl; //20
    delete csuper;
 
    csuper = new CashContext("打8折");
    total = total + csuper->getResult(4.0 * 5);
    cout << "單項價格:" << csuper->getResult(4.0 * 5) << endl; //16
    delete csuper;
 
    csuper = new CashContext("滿300返100");
    total = total + csuper->getResult(220.0 * 3);
    cout << "單項價格:" << csuper->getResult(220.0 * 3) << endl; //460
    delete csuper;
 
    cout << "最終的應該付款:" << total << endl; //496
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章