一、定義
策略模式定義了一系列的算法,並將每一個算法封裝起來,而且使它們還可以相互替換。策略模式讓算法獨立於使用它的客戶而獨立變化。
—抽象策略角色: 策略類,通常由一個接口或者抽象類實現。
—具體策略角色:包裝了相關的算法和行為。
—環境角色:持有一個策略類的引用,最終給客戶端調用。
二、圖分析
Context(應用場景):
1、需要使用ConcreteStrategy提供的算法。
2、內部維護一個Strategy的實例。
3、負責動態設置運行時Strategy具體的實現算法。
4、負責跟Strategy之間的交互和數據傳遞。
Strategy(抽象策略類):
1、定義了一個公共接口,各種不同的算法以不同的方式實現這個接口,Context使用這個接口調用不同的算法,一般使用接口或抽象類實現。
ConcreteStrategy(具體策略類):
2、實現了Strategy定義的接口,提供具體的算法實現。
自己的理解:Context通過實現Stragey定義的ContextInterface接口來調用相應的算法
三、代碼實現
1、客戶端
[csharp]
<SPAN style="FONT-SIZE: 18px">namespace _2._4策略模式
{
class Program
{
static void Main(string[] args)
{
Context context; //聲明對象
context = new Context(new ConcreteStrategyA()); //實例化對象同時實例化相應的算法類
context.ContexInterface(); //通過context調用具體算法
context = new Context(new ConcreteStrategyB());
context.ContexInterface();
context = new Context(new ConcreteStrategyC());
context.ContexInterface();
Console.Read();
}
}
<SPAN style="COLOR: #ff0000">
//Strtegy類,定義了所有支持的算法的公共接口,抽象算法類</SPAN>
abstract class Strategy
{
//算法方法
public abstract void AlgorithmInterface();
}
//ConcreteStrategy ,封裝了具體的算法或行為,繼承於Strategy;具體算法A
class ConcreteStrategyA : Strategy
{
<SPAN style="COLOR: #ff0000"> //算法A實現方法</SPAN>
public override void AlgorithmInterface()
{
Console.WriteLine ("算法A實現");
}
}
<SPAN style="COLOR: #ff0000"> //具體算法B</SPAN>
class ConcreteStrategyB : Strategy
{
//算法B實現方法
public override void AlgorithmInterface()
{
Console.WriteLine("算法B實現");
}
}
<SPAN style="COLOR: #ff0000"> //具體算法C</SPAN>
class ConcreteStrategyC : Strategy
{
//算法C實現方法
public override void AlgorithmInterface()
{
Console.WriteLine("算法C實現");
}
}
<SPAN style="COLOR: #ff0000"> //Context,用一個ConcreteStrategy來配置,維護一個隊Strategy對象的引用。上下文</SPAN>
class Context
{
Strategy strategy;
public Context(Strategy strategy)
{
this.strategy = strategy;
}
//上下文接口
public void ContexInterface()
{
strategy.AlgorithmInterface();
}
}
}</SPAN>
namespace _2._4策略模式
{
class Program
{
static void Main(string[] args)
{
Context context; //聲明對象
context = new Context(new ConcreteStrategyA()); //實例化對象同時實例化相應的算法類
context.ContexInterface(); //通過context調用具體算法
context = new Context(new ConcreteStrategyB());
context.ContexInterface();
context = new Context(new ConcreteStrategyC());
context.ContexInterface();
Console.Read();
}
}
//Strtegy類,定義了所有支持的算法的公共接口,抽象算法類
abstract class Strategy
{
//算法方法
public abstract void AlgorithmInterface();
}
//ConcreteStrategy ,封裝了具體的算法或行為,繼承於Strategy;具體算法A
class ConcreteStrategyA : Strategy
{
//算法A實現方法
public override void AlgorithmInterface()
{
Console.WriteLine ("算法A實現");
}
}
//具體算法B
class ConcreteStrategyB : Strategy
{
//算法B實現方法
public override void AlgorithmInterface()
{
Console.WriteLine("算法B實現");
}
}
//具體算法C
class ConcreteStrategyC : Strategy
{
//算法C實現方法
public override void AlgorithmInterface()
{
Console.WriteLine("算法C實現");
}
}
//Context,用一個ConcreteStrategy來配置,維護一個隊Strategy對象的引用。上下文
class Context
{
Strategy strategy;
public Context(Strategy strategy)
{
this.strategy = strategy;
}
//上下文接口
public void ContexInterface()
{
strategy.AlgorithmInterface();
}
}
}
四、適用情況(聯系生活和以前學習經驗)
機房收費系統中臨時用戶與固定用戶收費方式的差別。
應用場景:
1、多個類只區別在表現行為不同,可以使用Strategy模式,在運行時動態選擇具體要執行的行為。
2、需要在不同情況下使用不同的策略(算法),或者策略還可能在未來用其它方式來實現。
3、對客戶隱藏具體策略(算法)的實現細節,彼此完全獨立。
五、優缺點
優點:
1、提供了一種替代繼承的方法,而且既保持了繼承的優點(代碼重用)還比繼承更靈活(算法獨立,可以任意擴展)。
2、避免程序中使用多重條件轉移語句,使系統更靈活,並易於擴展。
3、高內聚、低偶合。
缺點:
1、因為每個具體策略類都會產生一個新類,所以會增加系統需要維護的類的數量。
解決方案:工廠方法
六、簡單工廠與策略模式的區別
1、 簡單工廠模式中我們只需要傳遞相應的條件就能得到想要的一個對象,然後通過這個對象實現算法的操作。
策略模式使用時必須首先創建一個想使用的類對象,然後將該對象作為參數傳遞進去,通過該對象調用不同的算法。
2、簡單工廠中實現了通過條件選取一個類去實例化對象,策略模式則將選取相應對象的共做交給模式的使用者,它本身不去做選取工作。
3、Factory是直接創建具體的對象並用該對象去執行相應的操作,而Context將這個操作給了Context類,沒有創建具體的對象,實現代碼的進一步封裝,客戶端代碼不需要知道具體的實現過程。