1. 程式人生 > >C++策略模式

C++策略模式

策略 想法 函數接口 易維 例如 www 設計思路 interface con

策略模式: 它定義了算法家族,分別封裝起來,讓它們之間可以相到替換,此模式用算法的變化不會影響到其它的客戶。 技術分享
此模式還是其實就是我們平常寫的代碼,其實設計模式就是告訴你如何寫代碼罷了,並不是什麽搬來就可以用的方案,如果是這樣,為鳥不直接寫在庫作框架調用就得了,因為它僅僅提供一種解決方案。它只是告訴你有與它相似需求的時候,代碼該怎麽寫。這樣寫出來的代碼它的擴展性好,容易維護,類之間的耦合度低。
策略模式迎合了幾個面向對象的設計思想: 1、找出應用中可能需要變化之處,把它們獨立出來,不要和那些不需要變化的代碼混在一起。 2、多用組合,少用繼承。 3、針對接口而不是實現編程。

引用《Head First 設計模式》中的例子: 假如我們要設一個鴨子類: 那麽一般的想法就是: 技術分享 在基類中,有fly(),swim(),quack()這些函數接口,然後在子類中只要實現這些接口就行了。但是問題來了,例如我們要實現一個“旱鴨子”和“橡皮鴨”。你會發現,感覺在設計上邏輯有點不太對了,像皮鴨會叫嗎?它會有quack()或者fly()函數接口嗎?而旱鴨子會有swim()方法?這些肯定是不對的。 問題在於這種設計思路不太符合: 2、多用組合,少用繼承。 原則,都用繼承就沒有那麽靈活了。
或者你會這麽設計: 技術分享 這樣也許是個好設計,把fly()和swim單獨弄出來作一個類,然後單獨繼承,這樣設計倒是符合: 1、找出應用中可能需要變化之處,把它們獨立出來,不要和那些不需要變化的代碼混在一起。
但是Acton類本來應該也是Duck該有的,Action應該是屬於Duck類。單獨分開來繼承,可能實現上沒有太大的影響 ,但是從邏輯上好像也不太好,好像有人非得把你“五馬分屍”。
所以總結下,這麽設計: 技術分享 也就是將Action作為Duck的成員,再在它自己的方法中調用Action中的接口。 技術分享
  1. voidDuck::peformfly(){
  2. this->action.fly();
  3. }

上面的框圖的,代碼實現。
  1. #include<iostream>
  2. #include<string>
  3. classStratery{
  4. public:
  5. Stratery
    (){
  6. }
  7. virtualvoidAlgorithmInterface(){
  8. std::cout<<"AlgorithmInterface"<<std::endl;
  9. }
  10. };
  11. classConcreteStrateryA:publicStratery{
  12. public:
  13. virtualvoidAlgorithmInterface(){
  14. std::cout<<"ConcreteStrateryA"<<std::endl;
  15. }
  16. };
  17. classConcreteStrateryB:publicStratery{
  18. public:
  19. virtualvoidAlgorithmInterface(){
  20. std::cout<<"ConcreteStrateryB"<<std::endl;
  21. }
  22. };
  23. classConcreteStrateryC:publicStratery{
  24. public:
  25. virtualvoidAlgorithmInterface(){
  26. std::cout<<"ConcreteStrateryC"<<std::endl;
  27. }
  28. };
  29. classContext{
  30. private:
  31. Stratery*stratery;
  32. public:
  33. Context(Stratery*_stratery):stratery(_stratery){
  34. }
  35. voidContextInterface(){
  36. stratery->AlgorithmInterface();
  37. }
  38. };
  39. int main(){
  40. Context contextA(newConcreteStrateryA());
  41. contextA.ContextInterface();
  42. Context contextB(newConcreteStrateryB());
  43. contextB.ContextInterface();
  44. Context contextC(newConcreteStrateryB());
  45. contextC.ContextInterface();
  46. }

上面的實現,就是使用了策略模式的經典用法。 其中:
  1. ConcreteStrateryA
  1. ConcreteStrateryB
  1. ConcreteStrateryC
就是算法家族。這些算法之間是沒有耦合的。這也是策略模式的要點之一。 可以說,策略模式就是用來封裝算法,但是也可以擴展到所有其它與之要求相似的類。例如前面的Duck類,那麽Duck類中封裝的算法就是 Action了。



null



C++策略模式