c++ 實現策略模式

來源:互聯網
上載者:User

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

上面是《大話設計模式》中給出的定義,感覺這個概念給的不好,看了之後不能完全清晰明白該模式(可能自己水平太水的原因吧)。在《effective c++》中指出,策略模式是virtual 函數的替換方法。仔細想想也差不多。如果想在不同的類中實現不同的演算法,那麼在基類中定義一個virtual函數,衍生類別給出不同的實現即可。這裡出現一個問題,如果要實現的演算法太多(演算法參數、傳回值等不同),那麼需要在基類中都進行virtual聲明,在具體的類中給出具體函數的實現。那麼每個衍生類別都需要繼承那麼多virtual 函數(而且多數沒用),衍生類別好臃腫啊。有人給出衍生類別減肥法,原廠模式,其實就是每個演算法給出一個實作類別外加多態的使用;別的方法,那就是每個演算法實現一個類,把這個類傳入到具體的過程類中,讓演算法類作為過程類的一個屬性,可以根據要求進行設定,當然這個演算法跟原廠模式有些相似處。(後面有兩者關係圖)

先描述一下應用情境吧,設計商場收費軟體,要求能夠滿足,不同的打折要求、不同的滿幾百送幾百的返利要求。比如:店慶打8折,國慶節滿300送100;

下面看一下,原廠模式和策略模式關係圖,看一下他們之間的差別:

原廠模式:

策略模式:

下面看一下傳統的策略模式的實現代碼:

#include<iostream>#include<string>using namespace std;class CashSuper{public:virtual double acceptCash(double money) = 0;};class CashNormal : public CashSuper{public :double acceptCash(double money){return money;}};class CashRebate : public CashSuper{public:CashRebate(double d = 1) : moneyRebate(d){}double acceptCash(double money);private:double moneyRebate; };double CashRebate::acceptCash(double money){return money * moneyRebate;}class CashReturn : public CashSuper{public:CashReturn(double mc = 0.0, double mr = 0.0) : moneyCondition(mc), moneyReturn(mr){}double acceptCash(double money);private:double moneyCondition;double moneyReturn;};double CashReturn::acceptCash(double money){double result = money;if (money > moneyCondition)result = money - (int)(money / moneyCondition)* moneyReturn;return result;}class CashContext{public :CashContext(CashSuper *cashuper) : cs(cashuper){}double GetResult(double money);private:CashSuper *cs;};double CashContext::GetResult(double money){return cs->acceptCash(money);}

上面的是傳統策略模式的實現代碼,但是只是個架構,很好看,不中用;沒有具體環境執行。

下面是策略模式和原廠模式結合的代碼,情景如上所述:其中1代表:正常模式收費;     2代表:滿300送100;   3代表:打8折。

將上面的CashContext替換成ConcreteCashContext就可以直接運行了。

class ConcreteCashContext{public:ConcreteCashContext(int type);double GetResult(double money);private:CashSuper *cs;};double ConcreteCashContext::GetResult(double money){return cs->acceptCash(money);}ConcreteCashContext::ConcreteCashContext(int type){switch(type){case 1:cs = new CashNormal();break;case 2:cs = new CashReturn(300,100);break;case 3:cs = new CashRebate(0.8);break;default:cout << " cant not recognize the type " << endl;}}int main(int argc, char **argv){ConcreteCashContext *ccc = new ConcreteCashContext(2);double money = 850.45;cout << " The moeny is : " << money << endl;cout << "you have to pay : " << ccc->GetResult(money) << endl;system("pause");return 0;}

參考:

1、《大話設計模式》

2、《effective c++》

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.