【設計模式基礎】行為模式 - 5 - 策略(Strategy)

王曉斌發表於2014-02-12

1. 模式意圖

策略模式別名Policy。

策略模式的意圖是針對一組演算法,將每個演算法封裝到具有共同介面的獨立的類中,從而使得他們可以相互替換。

策略模式使得演算法可以在不影響客戶端的情況下發生變化。


使用策略模式可以把行為和環境分割開來。環境類負責維持和查詢行為類,各種演算法則在具體策略類中提供。由於演算法和環境獨立開來,演算法的增減、修改都不會影響環境和客戶端。當出現新的變化時,只需要實現新的策略類,並在客戶端登記即可。


Note:策略模式並不決定何時使用何種演算法(策略)


策略模式 V.S. 橋接模式

  • Strategy模式注重於演算法的封裝;
  • Bridge模式注重於分離抽象和實現,為一個抽象體系提供不同的實現;


2. 模式定義



Context(上下文,環境):            用一個ConcreteStrategy物件來配置;維護一個對Strategy物件的引用;可定義一個介面讓Strategy訪問它的資料;

抽象策略(Strategy):                   定義一個介面或抽象類實現;定義所有支援的演算法的公共介面;Context使用這個介面來呼叫某ConcreteStrategy定義的演算法;

具體策略(ConcreteStretegy):  以Strategy介面實現某具體演算法;


3. 模式實現

3.1 C#實現策略模式

// Strategy pattern -- Structural example  
using System;

// "Strategy"
abstract class Strategy
{
  // Methods
  abstract public void AlgorithmInterface();
}

// "ConcreteStrategyA"
class ConcreteStrategyA : Strategy
{
  // Methods
  override public void AlgorithmInterface()
  {
    Console.WriteLine("Called ConcreteStrategyA.AlgorithmInterface()");
  }
}

// "ConcreteStrategyB"
class ConcreteStrategyB : Strategy
{
  // Methods
  override public void AlgorithmInterface()
  {
    Console.WriteLine("Called ConcreteStrategyB.AlgorithmInterface()");
  }
}

// "ConcreteStrategyC"
class ConcreteStrategyC : Strategy
{
  // Methods
  override public void AlgorithmInterface()
  {
    Console.WriteLine("Called ConcreteStrategyC.AlgorithmInterface()");
  }
}

// "Context"
class Context
{
  // Fields
  Strategy strategy;

  // Constructors
  public Context( Strategy strategy )
  {
    this.strategy = strategy;
  }

  // Methods
  public void ContextInterface()
  {
    strategy.AlgorithmInterface();
  }
}

/// <summary>
/// Client test
/// </summary>
public class Client
{
  public static void Main( string[] args )
  {
    // Three contexts following different strategies
    Context c = new Context( new ConcreteStrategyA() );
    c.ContextInterface();

    Context d = new Context( new ConcreteStrategyB() );
    d.ContextInterface();

    Context e = new Context( new ConcreteStrategyC() );
    e.ContextInterface();
  }
}


4. 模式應用

4.1 何時使用策略模式

  • 如果在一個系統裡面有許多類,他們之間的區別僅在於他們的行為,那麼使用策略模式可以動態地讓一個物件在許多行為中選擇一種行為。
  • 一個系統需要動態地在幾種演算法中選擇幾種。那麼這些演算法可以包裝到一個個的具體的演算法類裡面,而這些具體演算法類都是一個抽象演算法類的子類。換言之,這些具體演算法類均有統一的介面,由於多型原則,客戶端可以選擇使用任何一個具體演算法類,並只持有一個抽象演算法類的物件。
  • 一個系統的演算法使用的資料不可以讓客戶端知道;策略模式可以避免讓客戶端涉及到不必要接觸到的複雜的和只與演算法有關的資料。
  • 如果一個物件有很多的行為,如果使用不恰當的模式,這些行為就只好使用多重的條件選擇語句來實現。此時,使用策略模式,把這些行為轉移到相應的具體策略類裡面,就可以避免使用難以維護的多重條件選擇語句,並體現物件導向設計的概念。





相關文章