設計模式筆記:策略模式(Strategy)

libingql發表於2013-12-30

1. 策略模式簡介

1.1 定義

  策略是為達到某一目的而採取的手段或方法,策略模式的本質是目標與手段的分離,手段不同而最終達成的目標一致。客戶只關心目標而不在意具體的實現方法,實現方法要根據具體的環境因素而變化。

1.2 使用頻率

   中高

2. 策略模式結構圖

2.1 結構圖

2.2 參與者

  策略模式參與者:

  ◊ Strategy 策略

    ° 定義所支援的演算法的公共介面。Context使用這個介面來呼叫某個ConcreteStrategy定義的演算法。

  ◊ ConcreteStrategy 具體策略

    ° 實現Strategy介面中的具體演算法。

  ◊ Context 上下文

    ° 通過一個ConcreteStrategy物件來對其進行配置;

    ° 維護一個對Strategy物件的引用;

    ° 可定義一個介面來讓Strategy訪問它的資料。

3. 策略模式結構實現

  Strategy.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StrategyPattern.Structural
{
    public abstract class Strategy
    {
        public abstract void AlgorithmInterface();
    }
}

  ConcreteStrategyA.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StrategyPattern.Structural
{
    public class ConcreteStrategyA : Strategy
    {
        public override void AlgorithmInterface()
        {
            Console.WriteLine("Called ConcreteStrategyA.AlgorithmInterface()");
        }
    }
}

  ConcreteStrategyB.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StrategyPattern.Structural
{
    public class ConcreteStrategyB : Strategy
    {
        public override void AlgorithmInterface()
        {
            Console.WriteLine("Called ConcreteStrategyB.AlgorithmInterface()");
        }
    }
}

  ConcreteStrategyC.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StrategyPattern.Structural
{
    public class ConcreteStrategyC : Strategy
    {
        public override void AlgorithmInterface()
        {
            Console.WriteLine("Called ConcreteStrategyC.AlgorithmInterface()");
        }
    }
}

  Context.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StrategyPattern.Structural
{
    public class Context
    {
        private Strategy _strategy;

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

        public void ContextInterface()
        {
            _strategy.AlgorithmInterface();
        }
    }
}

  Program.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StrategyPattern.Structural
{
    class Program
    {
        static void Main(string[] args)
        {
            Context context;

            context = new Context(new ConcreteStrategyA());
            context.ContextInterface();

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

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

  執行結果:

4. 策略模式應用分析

4.1 策略模式適用情形

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

4.2 策略模式優點

(1)支援開閉原則(OCP)。

(2)策略模式使用繼承模式抽取公共程式碼到基類,避免重複程式碼。

(3)策略模式避免使用多重條件判斷語句(if/else、switch等)。

4.3 策略模式缺點

(1)客戶端(Client)必須知道所有的策略類,並自行決定使用哪一個策略類。策略模式只適用於客戶端知道所有的演算法或行為的情況。
(2)策略模式造成很多的策略類。

相關文章