再說設計模式-策略模式

定義

策略模式(Strategy Pattern)是一種比較簡單的模式,也叫政策模式(Policy Pattern)。其定義如下:

Define a family of algorithms, encapsulate each one, and make them interchangeable.
定義一組算法,將每個算法都封裝起來,並且使它們之間可以互換。

重點定義一組算法封裝, 算法之間可互換

策略模式的通用模型類圖如下:


  • Context封裝角色
    它作爲上下文角色,承上啓下的封裝作用,屏蔽高層模塊對策略、算法的直接訪問,封裝可能存在的變化。
  • Strategy抽象策略角色
    策略、算法家族的抽象,通常爲接口,定義每個策略或算法必須具有的方法和屬性。其中AlgorithmInterface爲算法的‘運算法則’。
  • ConcreteStrategy具體策略角色
    實現抽象策略中的操作,該類含有具體的算法。

模板代碼:

// 抽象的策略角色
public interface Strategy {
  // 策略模式的運算法則
  public void algorithmInterface();
}

// 具體策略角色
public class ConcreteStrategy1 implements Strategy {
  public void algorithmInterface() {
    // 具體策略1的運算法則
  }
}

// 封裝角色
public class Context {
  // 抽象策略
  private Strategy strategy = null;
  // 構造函數設置具體策略
  public Context(Strategy _strategy) {
    this.strategy = _strategy;
  }

  // 封裝後的策略方法
  public void doAnything() {
    this.strategy.algorithmInterface();
  }
}

最終高層模塊的調用非常簡單,知道要用哪個策略,產生出它的對象,然後放到封裝角色中就完成任務了,如下代碼:

public class Client {
  public static void main(String[] args) {
    // 聲明一個具體的策略
    Strategy strategy = new ConcreteStrategy1();
    // 聲明上下文對象
    Context context = new Context(Strategy);
    // 執行封裝後的方法
  }
}

策略模式就是這麼簡單。

策略模式的優點

  • 策略可以自由的切換
    只要實現抽象策略,它就成爲策略家族的一個成員,通過封裝角色對其進行封裝,保證對外提供“可自由切換”的策略。
  • 避免使用多重條件判斷
    使用策略模式後,可以由其他模塊決定採用何種策略,策略家族對外提供的訪問接口就是封裝類,簡化了操作,同時避免了條件語句判斷。
  • 擴展性良好
    它就像一個可以反覆拆卸的插件,這大大地符合了OCP原則。

策略模式的缺點

  • 策略類數量增多
    每一個策略都是一個類,複用的可能性很小,類數量增多。
  • 所有的策略類都需要對外暴露
    上層模塊必須知道有哪些策略,然後才能決定使用哪一個策略,這與迪米法則是相違背的。我只想使用一個策略,爲什麼要了解這個策略呢?這是原裝策略模式的一個缺點,不過我們可以使用工廠方法模式、代理模式或享元模式來修正這個缺陷。

策略模式的使用場景

  • 多個類只有在算法或行爲上稍有不同的場景
  • 算法需要自由切換的場景
  • 需要屏蔽算法規則的場景

策略模式的注意事項

如果系統中的一個策略家族的具體策略數量超過4個,則需要考慮使用混合模式,解決策略類膨脹和對外暴露的問題,否則日後的系統維護就會成爲一個誰也不想接的燙手山芋~~

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