1. 程式人生 > >Think in Java反芻筆記(5)---介面之策略設計模式

Think in Java反芻筆記(5)---介面之策略設計模式

 在Think in Java 的第九章介面中在9.3(完全解耦) 節中看到一個程式碼,貼出來如下:
  1.  import java.util.*;
  2.             
  3. class Processor {
  4.   public String name() {
  5.     return getClass().getSimpleName();
  6.   }
  7.   Object process(Object input) { return input; }
  8. }    

  9. class Upcase extends Processor {
  10.   String process(Object input) { // Covariant return
  11.     return ((String)input).toUpperCase();
  12.   }
  13. }

  14. class Downcase extends Processor {
  15.   String process(Object input) {
  16.     return ((String)input).toLowerCase();
  17.   }
  18. }

  19. class Splitter extends Processor {
  20.   String process(Object input) {
  21.     // The split() argument divides a String into pieces:
  22.     return Arrays.toString(((String)input).split(" "));
  23.   }
  24. }    

  25. public class Apply {
  26.   public static void process(Processor p, Object s) {
  27.     System.out.println("Using Processor " + p.name());
  28.     System.out.println(p.process(s));
  29.   }

  30.   public static String s =
  31.     "Disagreement with beliefs is by definition incorrect";

  32.   public static void main(String[] args) {
  33.      process(new Upcase(), s);
  34.      process(new Downcase(), s);
  35.      process(new Splitter(), s);
  36.   }
  37. }

      上文中用到的就是策略設計模式。 本人在上面的程式碼中也只是看到了抽象類而已,也就是說,有了Processor 抽象類,然後基類們繼承它,僅此而已。好吧,由於在本書中並沒有仔細講解這個模式。        先問自己幾個問題:
       1、策略模式是什麼? 2、有什麼用? 3、什麼場合用?  4、有什麼壞處?  5、給個程式碼例子吧。                 好奇心是一切智慧的來源。
       OK,開始自問自答模式。

  一、策略模式是什麼呢?

      《Java與模式》中這樣寫的,策略模式屬於物件的行為模式。其用意是針對一組演算法,將每一個演算法封裝到具有相同介面的獨立的類中,從而使得它們相互替換。策略模式使得演算法可以在不影響到客戶端的情況下發生變化。         有了定義,那就來分析定義:              1、說的是屬於物件的行為模式,也就是說這個模式最終針對的是物件的行為,是對物件的行為的高度抽象化,那麼為什麼要對物件的行為再高度抽象化呢?這裡還不知道,來看下面的              2、它的用意是針對一組演算法,將每一個演算法封裝到具有相同介面的獨立的類中,從而使得它們相互替換。這句話有點麻煩,它可能想說,將一個相同的一組演算法封裝到一個介面中。 類似於下面的程式碼:                            3、策略模式使得演算法可以在不影響客戶端的情況下發生變化。    這個是最終的目的。          

二、有什麼用啊?也就是說有什麼好處啊?

               可以一句話概括:可以動態的改變物件的行為,擴充套件性好啊。

 三、什麼場合用?

                1、如果在一個系統裡面有許多類,它們之間的區別僅在於它們的行為,那麼使用策略模式可以動態的讓一個物件在許多行為中選擇一種行為。                 2、一個系統需要動態的在幾種演算法中選擇一種。                 3、如果一個物件有很多的行為,如果不用恰當的模式,這些行為就只好使用多重的條件選擇語句來實現。
          註解:注意到了嗎?也就是說,如果說是都是計算,計算有加,減,乘,除四種的話,使用者可以選擇一種,那麼實現這個就可以使用策略模式。重點在於有多種選擇,而後選擇性的計算,如果不這麼幹,就只能用多重的條件選擇了。

四、有什麼壞處?

                              客戶端必須知道所有的策略類,並自行決定使用哪一個策略類。
             策略模式將造成產生很多策略類,可以通過使用享元模式在一定程度上減少物件的數量。

五、給個程式碼例子吧。

           
步驟 1
建立一個介面。
Strategy.java
public interface Strategy {
public int doOperation(int num1, int num2);
}
步驟 2
建立實現介面的實體類。
OperationAdd.java
public class OperationAdd implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 + num2;
}
}
OperationSubstract.java
public class OperationSubstract implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 - num2;
}
}
OperationMultiply.java
public class OperationMultiply implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 * num2;
}
}
步驟 3
建立 Context 類。
Context.java
public class Context {
private Strategy strategy;
public Context(Strategy strategy){
this.strategy = strategy;
}
public int executeStrategy(int num1, int num2){
return strategy.doOperation(num1, num2);
}
}
步驟 4
使用 Context 來檢視當它改變策略 Strategy 時的行為變化。
StatePatternDemo.java
public class StrategyPatternDemo {
public static void main(String[] args) {
Context context = new Context(new OperationAdd());  
System.out.println("10 + 5 = " + context.executeStrategy(10, 5));
      context = new Context(new OperationSubstract());  
System.out.println("10 - 5 = " + context.executeStrategy(10, 5));
      context = new Context(new OperationMultiply());  
System.out.println("10 * 5 = " + context.executeStrategy(10, 5));
}
}
步驟 5
驗證輸出。
10 + 5 = 15
10 - 5 = 5
10 * 5 = 50
        六、總結
  • 在策略模式中定義了一系列演算法,將每一個演算法封裝起來,並讓它們可以相互替換。策略模式讓演算法獨立於使用它的客戶而變化,也稱為政策模式。策略模式是一種物件行為型模式。
  • 策略模式包含三個角色:環境類在解決某個問題時可以採用多種策略,在環境類中維護一個對抽象策略類的引用例項;抽象策略類為所支援的演算法聲明瞭抽象方法,是所有策略類的父類;具體策略類實現了在抽象策略類中定義的演算法。
  • 策略模式是對演算法的封裝,它把演算法的責任和演算法本身分割開,委派給不同的物件管理。策略模式通常把一個系列的演算法封裝到一系列的策略類裡面,作為一個抽象策略類的子類。
  • 策略模式主要優點在於對“開閉原則”的完美支援,在不修改原有系統的基礎上可以更換演算法或者增加新的演算法,它很好地管理演算法族,提高了程式碼的複用性,是一種替換繼承,避免多重條件轉移語句的實現方式;其缺點在於客戶端必須知道所有的策略類,並理解其區別,同時在一定程度上增加了系統中類的個數,可能會存在很多策略類。
  • 策略模式適用情況包括:在一個系統裡面有許多類,它們之間的區別僅在於它們的行為,使用策略模式可以動態地讓一個物件在許多行為中選擇一種行為;一個系統需要動態地在幾種演算法中選擇一種;避免使用難以維護的多重條件選擇語句;希望在具體策略類中封裝演算法和與相關的資料結構。