Head First 設計模式讀書筆記(1)-策略模式


一、策略模式的定義

策略模式定義了算法族,分別封裝起來,讓它們之間可以互換替換,此模式讓算法的變化獨立使用算法的客戶。

二、使用策略模式的一個例子

2.1引出問題

某公司做了一套模擬鴨子的游戲:該游戲會出現各種鴨子,他們具有相似點(都會叫,會游泳,會表達自己的特征)和異同點(每種展示自己的特征是不同的方法),很容易想到使用OO技術,定義個鴨子超類,讓其他的鴨子類來繼承鴨子超類。

由於異同點都會展示自己的特征,只是展示特征方式不同,所以在超類中特征的方法是抽象或者使用一個接口(在此就使用接口,因為每一個類都會有展示方法)。下面給出其類圖。

image

可當某一天發現了問題,

問題1:如果出現了一個DuckC,展示方式和DuckA相同,都是使用相同的方法,那么就會在DuckC類中寫了同樣的代碼,如果那一天想修改他們中的使用相同的方法,就要一個個去修改,如果是有多個的話,就容易出現問題,而且不能到達方法復用的效果。

問題2:如果想讓一只鴨子需要有兩種不同的展示方式,可能隨時改變展示方式,上面的設計就需要修改了

2.2分析問題

問題1為了達到復用,是不可能把所有的展示方式放到Duck類中,因為對應DuckA和DuckB以及DuckC可以隨便調用方法,顯然是不明智的。

先把問題1放一放,我們來看一下問題2的,可以隨時改變,C#中有個屬性的思想不就是可以隨時改變變量的值。是不是可以使用相同的方法來實現呢。每次使用set時,是讓值賦給指定的變量,而且可以達到復用的目的(如Person p=new Person();p.Age=22,22是一個int類型中的一個對象,可以多次使用,而且還可以賦值為23)。一句簡單的屬性賦值,隱含着多種設計原則。

原則一:找出應用中可能需要變化之處,把它們獨立出來,不要和那些不需要變化的代碼混在一起。

在上面一段簡單的代碼中,我們可以把22,23看成計算機為我們封裝好的類型。22和23是被獨立出來的會變化的代碼。具體的實現我們不需要知道怎么實現。只需要知道表示的一個數。

原則二:針對接口編程,而不是針對實現編程。

先簡單的說一下上面的意思:讓變的抽象成接口或者抽象類,然后通過單獨的類來把接口實現或繼承抽象類來實現,而不是將功能直接在代碼中實現。

在上面具體的23和22怎么的實現我們是沒有直接寫出new int();而是直接獲取的類型,其實現交給計算機去處理。

原則三:多使用組合,少使用繼承

為什么能隨時“改變age”,這就是組合的力量,如果是使用繼承的話,就不能在一個過程中改變age。

上面使用整型可能有些不妥,僅僅作為一中理解形式。如果非要找一下策略模式在.net中的蹤影,可以看一下ArrayList的Sort(IComparer comparer)方法,可以參考http://www.cnblogs.com/justinw/archive/2007/02/06/641414.html

有了這三個原則,我覺得上面的兩個問題應該可以解決了。

2.3解決問題

使用組合和屬性的設計方法來處理

image

下面列出測試代碼:

         Duck dA = new DuckA(); 
          IDisplay displayA= dA.GetDisplay(); 
          displayA.Display(); 
          Console.WriteLine("A類鴨子展示方法:");

           Console.WriteLine("================================");

          Duck dB = new DuckB(); 
          IDisplay displayB = dB.GetDisplay(); 
          Console.WriteLine("B類鴨子展示方法:");

          displayB.Display(); 
           Console.WriteLine("================================");

          Duck dC = new DuckC(); 
          IDisplay displayC = dC.GetDisplay();

          Console.WriteLine("C類鴨子展示方法:");

          displayC.Display(); 
          Console.WriteLine("================================"); 
          dC.SetDisplay(new DisplayClassA()); 
          Console.WriteLine("C類鴨子改變方法后展示方法:"); 
          dC.GetDisplay().Display(); 
          Console.Read(); 
View Code

 

輸出結果:image

三、策略模式對應的UML

image

該模式也體現了面向對象的基本特征:封裝(把算法一個個封裝起來),繼承(接口的實現也可以看成是實現類“繼承”了接口),多態(在Context調用接口的時間,開始並不知道接口的方法的具體實現,但是知道有個方法,使用的時間就可獲取,調用)。

源碼  

四、小結

本文主要通過鴨子的設計,引出問題,分析問題,解決問題來體現了策略模式的靈活性,在分析過程中提出了三個設計原則,結合屬性的實現思想來解決了問題。本文是屬於讀書筆記,可能在理解的地方有偏差,希望能夠多多指教!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM