定義
策略是為達到某一目的而采取的手段或方法,策略模式的本質是目標與手段的分離,手段不同而最終達成的目標一致。客戶只關心目標而不在意具體的實現方法,實現方法要根據具體的環境因素而變化。
C#例子
// 上傳附件策略
public abstract class Strategy
{
// 上傳附件
public abstract void UpLoad();
}
// 使用阿里云的策略
public class AliYunStrategy : Strategy
{
public override void UpLoad()
{
Console.WriteLine("我把數據存到了阿里云!");
}
}
// 本地策略
public class LocalStrategy : Strategy
{
public override void UpLoad()
{
Console.WriteLine("我把數據存到了本地文件夾!");
}
}
public class MongoDbStrategy : Strategy {
public override void UpLoad()
{
Console.WriteLine("我把數據存到了芒果數據庫!");
}
}
public class Context
{
private Strategy _strategy;
public Context(Strategy strategy) {
_strategy = strategy;
}
public void UploadFile() {
_strategy.UpLoad();
}
}
static void Main(string[] args)
{
new Context(new AliYunStrategy()).UploadFile();
new Context(new LocalStrategy()).UploadFile();
new Context(new MongoDbStrategy()).UploadFile();
Console.ReadLine();
}
策略模式參與者:
- Strategy 策略: 定義所支持的算法的公共接口。Context使用這個接口來調用某個*Strategy定義的算法。
- *Strategy 具體策略: 實現Strategy接口中的具體算法。
- Context 上下文: 通過一個*Strategy對象來對其進行配置;維護一個對Strategy對象的引用;可定義一個接口來讓Strategy訪問它的數據。
策略模式適用情形:
- 如果在一個系統里面有許多類,它們之間的區別僅在于它們的行為,那么使用策略模式可以動態地讓一個對象在許多行為中選擇一種行為。
- 一個系統需要動態地在幾種算法中選擇一種。這些具體算法類均有統一的接口,由于多態性原則,客戶端可以選擇使用任何一個具體算法類,并只持有一個數據類型是抽象算法類的對象。
- 一個系統的算法使用的數據不可以讓客戶端知道。策略模式可以避免讓客戶端涉及到不必要接觸到的復雜的和只與算法有關的數據。
- 如果一個對象有很多的行為,如果不用恰當的模式,這些行為就只好使用多重的條件選擇語句來實現。此時,使用策略模式,把這些行為轉移到相應的具體策略類里面,可以避免使用難以維護的多重條件選擇語句。
策略模式優點:
- 策略模式恰當使用繼承可以把公共的代碼移到父類里面,從而避免重復的代碼。
- 策略模式提供了可以替換繼承關系的辦法。繼承可以處理多種算法或行為。如果不是用策略模式,那么使用算法或行為的環境類就可能會有一些子類,每一個子類提供一個不同的算法或行為。但是,這樣一來算法或行為的使用者就和算法或行為本身混在一起。決定使用哪一種算法或采取哪一種行為的邏輯就和算法或行為的邏輯混合在一起,從而不可能再獨立演化。繼承使得動態改變算法或行為變得不可能。
- 使用策略模式可以避免使用多重條件判斷語句。
策略模式缺點:
- 客戶端必須知道所有的策略類,并自行決定使用哪一個策略類。策略模式只適用于客戶端知道所有的算法或行為的情況。
- 策略模式造成很多的策略類。
其他
源碼地址
其他設計模式