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

1、策略模式的定義

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

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

2.1引出問題

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

因爲異同點都會展現本身的特徵,只是展現特徵方式不一樣,因此在超類中特徵的方法是抽象或者使用一個接口(在此就使用接口,由於每個類都會有展現方法)。下面給出其類圖。編程

image

可當某一天發現了問題,ide

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

問題2:若是想讓一隻鴨子須要有兩種不一樣的展現方式,可能隨時改變展現方式,上面的設計就須要修改了spa

2.2分析問題

問題1爲了達到複用,是不可能把全部的展現方式放到Duck類中,由於對應DuckA和DuckB以及DuckC能夠隨便調用方法,顯然是不明智的。.net

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

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

在上面一段簡單的代碼中,咱們能夠把22,23當作計算機爲咱們封裝好的類型。22和23是被獨立出來的會變化的代碼。具體的實現咱們不須要知道怎麼實現。只須要知道表示的一個數。htm

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

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

在上面具體的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

3、策略模式對應的UML

image

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

源碼  

4、小結

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

相關文章
相關標籤/搜索