網頁

2012年6月26日 星期二

Strategy 策略模式

何謂策略模式:

定義各別的演算法並將其封裝起來,讓他們之間可以互相替換,此模式讓演算法的變動,不會影響使用演算法的程式。

image_thumb1

由上面的UML圖可以得知Strategy類別只是一個演算法介面,而ConcreteStrategyA、B、C是真正實作的演算法內容,而Context是真正使用演算法的類別。

 

從上面的UML圖我們更可以發現兩個重點:

 

※ 寫程式是針對介面撰寫,而不是針對實踐方式。

 

※ 將程式中可能需要變動之處,取出並封裝起來,以後便可以輕易低擴充此部分,而不影響不需要更動的其他部分

 

在未來我們可以增加ConcreteStrategyD,E,F而不會去影響原有的程式功能。

為何使用策略模式:

 

因為可以動態的更換使用的演算法而不變動到使用演算法的程式。我們捨棄繼承而改用合成,降低程式之間的耦合度。

 

策略模式應該在演算法彼此有關聯性時使用,演算法應該各別封裝,本就不應該有任何關聯性。

 

ex:

我們這邊以遊戲中的武器系統來作範例,當我們有不同武器,攻擊的時候,應該會有不同的結果發生,例如武器攻擊時的特效,武器造成的傷害等等…………………。

 

假如沒有使用策略模式,那我們的code或許會像下列一樣:

  1: #define HANDGUN 1
  2: #define MACHINEGUN 2
  3: …
  4: int iCurrentWeapon
  5: …
  6: if ( iCurrentWeapon == HANDGUN )
  7: 
  8: {
  9:     FireHandgun();
 10: }
 11: else if ( iCurrentWeapon == MACHINEGUN )
 12: {
 13:     FireMachinegun();
 14: }

接著你就會發現,當你有新的武器的時候,你必須加入新的if…else if…必須不斷的在更動你使用武器系統類別程式的Code,在這過程中可能很容易發生錯誤,而且難以擴充以及維護。


 


假如使用了策略模式:


image


或許就會像上述的UML圖相似,而且我們還可以擴充至除了武器以外的子彈系統,我們可能會使用同一把槍,但是因為子彈種類不相同而有不同的效果,但是我們並不需要去更動到使用武器類別以及子彈類別的程式。


 


在遊戲中,我們可能還會有其他的例子,像是遊戲中最重要的Module切換,我們所有Module都有相同的介面,但是會因為Module的種類不同,而有不同的實作方法。


 


如下列UML圖,在GamePlayModule中,我們可能需要一直處理遊戲中的邏輯,以及Render遊戲畫面,但是在GameMain Module或許是顯示該顯示的UI等等…………。


 


image


這個模式是不是百利而無一害呢?很可惜,每個模式有他的優點,相對的也會有他的缺點存在。


 


在策略模式中,我們可能會因為想把許多演算法分類的更仔細,所可能會產生出很多很多的行為小類別

沒有留言:

張貼留言