[Design Pattern] 策略(Strategy)模式 - 把變化給封裝起來

  • 3649
  • 0
  • 2012-02-15

[Design Pattern] 策略(Strategy)模式 - 把變化給封裝起來

策略模式:

定義完成相同工作的一系列演算法,這些個別的演算法都是針對某個特定相同的工作

,差別在於各別演算法本身的商業邏輯不同,將這些演算法個別封裝起來便於抽換,

維護上彼此間是獨立的,不會因某個演算法的修改,而影響到其它的演算法,而慨念

上外界調用的方式是相同的。

 

 

情境示範:

棒球打擊,有不同的打擊策略,強力揮擊、選球巧打、短打、突襲短打,但若以抽象

角度來看,不管哪一種打擊策略都叫做打擊,差別在於打擊用的力道等細部內容的不同

 

參在一起做瀨尿牛丸寫法:

/// <summary>
       /// <summary>
/// 打擊
/// </summary>
/// <param name="swimtype">打擊型態</param>
public void Swim(string swimtype)
{

    switch (swimtype)
    {
        case "Power":
            //強力揮擊
            break;
        case "Bunt":
            //短打
            break;
        case "Squeeze Bunt":
            //突襲短打
            break;
        case "Clever":
            //選球巧打
            break;
    }
}

這樣的寫法把不同的打擊策略內容細部的Logic全寫在一起,用條件式的寫法分開,缺點在於

日後策略若有增減則要拿出來調整,一不小心容易動到不應動的程式Logic,此外變動的是打

擊策略內容,而非打擊的這個動作,這樣的設計方式違反開放-封閉原則,且程式碼也會變

的又臭又長。

 

 

運用Strategy Pattern的寫法:

(1)首先為打擊這件事建立一個抽象類別(可以是interface or abstract ),定義一個執行揮棒的方法

image

/// <summary>
/// 抽象策略的角色:
/// 做為實體化策略的接口
/// </summary>
public interface ISwimStrategy
{
	void Exec();
} 

(2)針對不同的打擊策略,建立各自的class,並繼承ISwimStrategy介面且實作其Exec方法

image

public class CleverSwim:ISwimStrategy 
{
	/// <summary>
	/// 實作選球巧打打擊策略Logic
	/// </summary>
	public void Exec()
	{
	    System.Web.HttpContext.Current.Response.Write("選球巧打");
	}
}

 

 

(3)接著打擊是棒球中的一個動作過程,因此我們建立一個名為BaseBall的Class,並且有著打擊

這個方法,而該方法的執行則是利用ISwimStrategy建立具可抽換的機制

image

image

 

(4)外界的呼叫

 DesignPattern.Strategy.BaseBall baseball = new DesignPattern.Strategy.BaseBall();

            baseball.Swim(new DesignPattern.Strategy.PowerSwim());

 

因此整個架構看起來會清爽的多,而且每個打擊策略內部Logic調整變動,均不會對其它的Class產生

影響,只要確保對外都是利用ISwimStrategy介面來做為接口就可以,彼此間偶合程度可以降低,以

後只要有新的打擊策略要增加,只需要再建立另一個新的打擊策略Class,並繼承ISwimStrategy介面

,實作Exec()即可

 

結論:

從這裡我們可以看的出來,Stategy模式在於把變化的部份給封裝起來,外界不需要去了解如何變化,

只需要知道想選用哪一種,並用共同的方式進行呼叫執行,此外這樣的模式也便於我們抽換不同的實作

Logic,不需要為了擴充而把不相干或不會動到的類別給打開來進行修改,一來也避免了因擴充了B,而

使用原本的A可能壞掉的風險

 

image

 

 

以上若有描述不當的地方,歡迎指正囉微笑

 

 

 

 

若本文對您有所幫助,歡迎轉貼,但請在加註【轉貼】及來源出處,並在附上本篇的超連結,感恩您的配合囉。

By No.18