Java設計模式之策略模式(轉)

java設計模式之——策略模式

 本文轉載自http://yangguangfu.iteye.com/blog/815107

1,什麼是策略模式?

策略模式,又叫算法簇模式,就是定義了不同的算法族,並且之間可以互相替換,此模式讓算法的變化獨立於使用算法的客戶。

 

2,策略模式有什麼好處?

     策略模式的好處在於你可以動態的改變對象的行爲。

 

3,設計原則

  
     設計原則是把一個類中經常改變或者將來可能改變的部分提取出來,作爲一個接口(c++z中可以用虛類),然後在類中包含這個對象的實例,這樣類的實例在運行時就可以隨意調用實現了這個接口的類的行爲。下面是一個例子。 


      策略模式屬於對象行爲型模式,主要針對一組算法,將每一個算法封裝到具有共同接口的獨立的類中,從而使得它們可以相互替換。策略模式使得算法可以在不影響 到客戶端的情況下發生變化。通常,策略模式適用於當一個應用程序需要實現一種特定的服務或者功能,而且該程序有多種實現方式時使用。

 

4 ,策略模式中有三個對象:
(1)       環境對象:該類中實現了對抽象策略中定義的接口或者抽象類的引用。
(2)       抽象策略對象:它可由接口或抽象類來實現。
(3)       具體策略對象:它封裝了實現同不功能的不同算法。
利用策略模式構建應用程序,可以根據用戶配置等內容,選擇不同有算法來實現應用程序的功能。具體的選擇有環境對象來完成。採用這種方式可以避免由於使用條件語句而帶來的代碼混亂,提高應用程序的靈活性與條理性。

 

5,應用場景舉例:

 

劉備要到江東娶老婆了,走之前諸葛亮給趙雲(伴郎)三個錦囊妙計,說是按天機拆開能解決棘手問題,嘿,還別說,真解決了大問題,搞到最後是周瑜陪了夫人又折兵,那咱們先看看這個場景是什麼樣子的。

 

先說說這個場景中的要素:三個妙計,一個錦囊,一個趙雲,妙計是亮哥給的,妙計放在錦囊裏,俗稱就是錦囊妙計嘛,那趙雲就是一個幹活的人,從錦囊取出妙計,執行,然後獲勝。用java程序怎麼表現這些呢?

那我們先來看看圖?


 

三個妙計是同一類型的東西,那咱就寫個接口:

Java代碼  收藏代碼
  1. package com.yangguangfu.strategy;  
  2. /** 
  3.  *  
  4.  * @author [email protected]:阿福 
  5.  * 首先定義一個策略接口,這是諸葛亮老人家給趙雲的三個錦囊妙計的接口。 
  6.  */  
  7. public interface IStrategy {  
  8.     //每個錦囊妙計都是一個可執行的算法。  
  9.     public void operate();  
  10.   
  11. }  
 

然後再寫三個實現類,有三個妙計嘛:

 

妙計一:初到吳國:

Java代碼  收藏代碼
  1. package com.yangguangfu.strategy;  
  2. /** 
  3.  *  
  4.  * @author [email protected]:阿福 
  5.  * 找喬國老幫忙,使孫權不能殺劉備。 
  6.  */  
  7. public class BackDoor implements IStrategy {  
  8.   
  9.     @Override  
  10.     public void operate() {  
  11.         System.out.println("找喬國老幫忙,讓吳國太給孫權施加壓力,使孫權不能殺劉備...");  
  12.     }  
  13.   
  14. }  
 

妙計二:求吳國太開個綠燈,放行:

Java代碼  收藏代碼
  1. package com.yangguangfu.strategy;  
  2. /** 
  3.  *  
  4.  * @author [email protected]:阿福 
  5.  * 求吳國太開個綠燈。 
  6.  */  
  7. public class GivenGreenLight implements IStrategy {  
  8.   
  9.     @Override  
  10.     public void operate() {  
  11.         System.out.println("求吳國太開個綠燈,放行!");  
  12.           
  13.     }  
  14.   
  15. }  

 妙計三:孫夫人斷後,擋住追兵:

Java代碼  收藏代碼
  1. package com.yangguangfu.strategy;  
  2. /** 
  3.  *  
  4.  * @author [email protected]:阿福 
  5.  * 孫夫人斷後,擋住追兵。 
  6.  */  
  7. public class BlackEnemy implements IStrategy {  
  8.   
  9.     @Override  
  10.     public void operate() {  
  11.         System.out.println("孫夫人斷後,擋住追兵...");  
  12.   
  13.     }  
  14.   
  15. }  

 

好了,大家看看,三個妙計是有了,那需要有個地方放妙計啊,放錦囊裏:

 

Java代碼  收藏代碼
  1. package com.yangguangfu.strategy;  
  2. /** 
  3.  *  
  4.  * @author [email protected]:阿福 
  5.  * 
  6.  */  
  7. public class Context {  
  8.       
  9.     private IStrategy strategy;  
  10.     //構造函數,要你使用哪個妙計  
  11.     public Context(IStrategy strategy){  
  12.         this.strategy = strategy;  
  13.     }  
  14.       
  15.     public void operate(){  
  16.         this.strategy.operate();  
  17.     }  
  18.   
  19. }  
 

 

然後就是趙雲雄赳赳的揣着三個錦囊,拉着已步入老年行列,還想着娶純情少女的,色咪咪的劉備老爺子去入贅了,嗨,還別說,亮哥的三個妙計還真不錯,瞧瞧:

Java代碼  收藏代碼
  1. package com.yangguangfu.strategy;  
  2.   
  3. public class ZhaoYun {  
  4.   
  5.     /** 
  6.      * 趙雲出場了,他根據諸葛亮給他的交代,依次拆開妙計 
  7.      */  
  8.     public static void main(String[] args) {  
  9.         Context context;  
  10.           
  11.         //剛到吳國的時候拆開第一個  
  12.         System.out.println("----------剛剛到吳國的時候拆開第一個---------------");  
  13.         context = new Context(new BackDoor());  
  14.         context.operate();//拆開執行  
  15.         System.out.println("\n\n\n\n\n\n\n\n\n\n\n\n\n");  
  16.           
  17.         //當劉備樂不思蜀時,拆開第二個  
  18.         System.out.println("----------劉備樂不思蜀,拆第二個了---------------");  
  19.         context = new Context(new GivenGreenLight());  
  20.         context.operate();//拆開執行  
  21.         System.out.println("\n\n\n\n\n\n\n\n\n\n\n\n\n");  
  22.           
  23.         //孫權的小追兵了,咋辦?拆開第三個錦囊  
  24.         System.out.println("----------孫權的小追兵了,咋辦?拆開第三個錦囊---------------");  
  25.         context = new Context(new BlackEnemy());  
  26.         context.operate();//拆開執行  
  27.         System.out.println("\n\n\n\n\n\n\n\n\n\n\n\n\n");  
  28.     }  
  29.   
  30. }  
 

後話:就這三招,搞得的周郎是“賠了夫人又折兵”呀!這就是策略模式,高內聚低耦合的特點也表現出來了,還有一個就是擴展性,也就是OCP原則,策略類可以繼續添加下去氣,只是修改Context.java就可以了,這個不多說了,自己領會吧。


策略模式和工廠模式的區別

本文轉載自http://xiewenbo.iteye.com/blog/1294207


工廠模式是創建型模式 
策略模式是行爲性模式 
一個關注對象創建 
一個關注行爲的封裝 
策略模式就是定義一系列的算法,這些算法可以在需要的時候替換和擴展.工廠模式是生成型的模式,在你需要的時候構建具體的實例. 

在下面的情況下應當考慮使用策略模式: 
1. 如果在一個系統裏面有許多類,它們之間的區別僅在於它們的行爲,那麼使用策略模式可以動態地讓一個對象在許多行爲中選擇一種行爲。 
2. 一個系統需要動態地在幾種算法中選擇一種。那麼這些算法可以包裝到一個個的具體算法類裏面,而這些具體算法類都是一個抽象算法類的子類。換言之,這些具體算法類均有統一的接口,由於多態性原則,客戶端可以選擇使用任何一個具體算法類,並只持有一個數據類型是抽象算法類的對象。 
3. 一個系統的算法使用的數據不可以讓客戶端知道。策略模式可以避免讓客戶端涉及到不必要接觸到的複雜的和只與算法有關的數據。 
4. 如果一個對象有很多的行爲,如果不用恰當的模式,這些行爲就只好使用多重的條件選擇語句來實現。此時,使用策略模式,把這些行爲轉移到相應的具體策略類裏面,就可以避免使用難以維護的多重條件選擇語句,並體現面向對象設計的概念。 

策略模式的優點和缺點 
策略模式有很多優點和缺點。它的優點有: 
1. 策略模式提供了管理相關的算法族的辦法。策略類的等級結構定義了一個算法或行爲族。恰當使用繼承可以把公共的代碼移到父類裏面,從而避免重複的代碼。 
2. 策略模式提供了可以替換繼承關係的辦法。繼承可以處理多種算法或行爲。如果不是用策略模式,那麼使用算法或行爲的環境類就可能會有一些子類,每一個子類提供一個不同的算法或行爲。但是,這樣一來算法或行爲的使用者就和算法或行爲本身混在一起。決定使用哪一種算法或採取哪一種行爲的邏輯就和算法或行爲的邏輯混合在一起,從而不可能再獨立演化。繼承使得動態改變算法或行爲變得不可能。 
3. 使用策略模式可以避免使用多重條件轉移語句。多重轉移語句不易維護,它把採取哪一種算法或採取哪一種行爲的邏輯與算法或行爲的邏輯混合在一起,統統列在一個多重轉移語句裏面,比使用繼承的辦法還要原始和落後。
策略模式的缺點有: 
1. 客戶端必須知道所有的策略類,並自行決定使用哪一個策略類。這就意味着客戶端必須理解這些算法的區別,以便適時選擇恰當的算法類。換言之,策略模式只適用於客戶端知道所有的算法或行爲的情況。 
2. 策略模式造成很多的策略類。有時候可以通過把依賴於環境的狀態保存到客戶端裏面,而將策略類設計成可共享的,這樣策略類實例可以被不同客戶端使用。換言之,可以使用享元模式來減少對象的數量。 

策略模式與很多其它的模式都有着廣泛的聯繫。Strategy很容易和Bridge模式相混淆。雖然它們結構很相似,但它們卻是爲解決不同的問題而設計的。Strategy模式注重於算法的封裝,而Bridge模式注重於分離抽象和實現,爲一個抽象體系提供不同的實現。Bridge模式與Strategy模式都很好的體現了"Favor composite over inheritance"的觀點。 



 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章