策略模式(Strategy Pattern)是一種行為型設計模式,它由以下幾個主要元素組成:
上下文(Context):上下文是包含一個策略的類別,它擁有一個策略介面的參考,並通常具有一個方法用於設定策略,以及其他方法用於執行策略。
策略介面(Strategy Interface):策略模式定義了一個策略介面,它包含一組方法,這些方法是不同策略實現必須實現的。
具體策略(Concrete Strategies):具體策略是實現策略介面的具體類別,每個具體策略都實現了策略介面中的方法,以提供不同的策略實現。
上下文使用策略(Context Using Strategy):上下文類別使用策略介面的參考來設置和切換不同的具體策略。
簡而言之,策略模式主要用於在運行時選擇不同的算法,
在一開始有說過行為型模式(Behavioral Patterns),
是有點像是介面的,主要是在不同的object之間的協作,
更偏向各個角色之間的相互作用,
那麼有說是if...else和策略模式的實現方式。
說到這就會想起第十四日所說的簡單工廠模式。
筆者在之前是用字典,
但其實用if...else也可以,
也是非常常用的一種形式。
那麼兩者最大的不同,
就是一個已知,
一個未知。
再施展一個策略的時候,
不可能會施展一個我不知道的策略,
這樣想想到奇怪,
帶來這邊,
也很明確的就是會知道有這個策略,
而我想使用這個策略。
而這就代表一件事情,
Client是知道內部有什麼策略的,
而這就是與簡單工廠最大的不同。
舉個例子,
在開車的時候常常會有切換檔位,
簡單分為爬坡時的低檔、加速的高檔跟後退的倒檔。
使用者就會根據需要的狀況去切換檔位。
public interface ITransmissionStrategy
{
string Shift();
}
public class LowGearStrategy : ITransmissionStrategy
{
public string Shift()
{
return "低檔:適合在爬坡使用。";
}
}
public class HighGearStrategy : ITransmissionStrategy
{
public string Shift()
{
return "高檔:提供更高的速度。";
}
}
public class ReverseGearStrategy : ITransmissionStrategy
{
public string Shift()
{
return "倒檔:用於後退行駛。";
}
}
public class Car
{
private ITransmissionStrategy _transmissionStrategy;
public Car(ITransmissionStrategy transmissionStrategy)
{
_transmissionStrategy = transmissionStrategy;
}
public void SetTransmissionStrategy(ITransmissionStrategy transmissionStrategy)
{
_transmissionStrategy = transmissionStrategy;
}
public string Shift()
{
return _transmissionStrategy.Shift();
}
}
class Program
{
static void Main(string[] args)
{
Car car = new Car(new LowGearStrategy());
// 使用低檔策略
string lowGearShift = car.Shift();
Console.WriteLine(lowGearShift);
// 切換到高檔策略
car.SetTransmissionStrategy(new HighGearStrategy());
string highGearShift = car.Shift();
Console.WriteLine(highGearShift);
// 切換到倒檔策略
car.SetTransmissionStrategy(new ReverseGearStrategy());
string reverseGearShift = car.Shift();
Console.WriteLine(reverseGearShift);
}
}
那麼第十三天筆者有提過,行為型模式(Behavioral Patterns)角色之間的相互作用,
那麼是不是代表著一定要一個object以上才能進行呢?
從以上的介紹能明顯發現,
其實可以不用,
就如同這裡只有一個car,
依然可以自然得切換檔位。
上下文(Context):上下文是包含一個策略的類別,它擁有一個策略介面的參考。
在這裡很明確的是car這個class,而裡面透過SetTransmissionStrategy 設定策略。
策略介面(Strategy Interface):在這邊有著通用interface,也就是ITransmissionStrategy ,
而這個就是用來新增修改策略用的,而不會去影響到Context,也就是開發封閉原則(OCP)的延伸。
具體策略(Concrete Strategies):
也就是實際實現的程式,低檔高檔與倒檔,
LowGearStrategy、HighGearStrategy與ReverseGearStrategy他們去實現了interface,
提供了不同的實際策略。
上下文使用策略(Context Using Strategy):
也就是car這個Class是怎麼使用策略的,
以這個例子而言,
是透過Shift這個function,
來執行當前需要什麼策略。