生活案例
跟不同類型的MM約會,要用不同的策略,有的請電影比較好,有的則去吃小吃效果不錯,有的去海邊浪漫最合適,單目的都是為了得到MM的芳心,關鍵是追MM錦囊中有好多Strategy哦。
電腦中的動機
而軟體構建過程中,某些對象使用的演算法可能多種多樣,經常改變,如果將這些演算法都編碼對象中,將會使對象變得異常複雜;而且有時候支援不使用的演算法也是一個效能負擔。
如何在運行時根據需要透明地更改對象的演算法?將演算法與對象本身解耦,從而避免上述問題?
概念
策略模式定義了演算法家庭,分別封裝起來,讓它們之間可以互相替換,此模式讓演算法的變化,不會影響到使用演算法的客戶。————《設計模式》GOF
圖
代碼
Strategy類,定義所有支援的演算法的公用介面
//抽象演算法類abstract class Strategy{ //演算法方法 public abstract void AlgorithmInteface();}
ConcreteStrategy,封裝了具體的演算法或行為,繼承於Strategy
//具體演算法Aclass ConcreteStrategyA : Strategy{ //演算法A實現方法 public override void AlgorithmInteface() { Console.WriteLine("演算法A實現"); }}//具體演算法Bclass ConcreteStrategyB : Strategy{ //演算法B實現方法 public override void AlgorithmInteface() { Console.WriteLine("演算法B實現"); }}//具體演算法Cclass ConcreteStrategyC : Strategy{ //演算法C實現方法 public override void AlgorithmInteface() { Console.WriteLine("演算法C實現"); }}
Context,用一個ConcreteStrategy來配置,維護一個對Strategy對象的引用
//上下文class Context{ Strategy strategy; public Context(Strategy strategy) { this.strategy = strategy; } //上下文介面 public void ContextInterface() { strategy.AlgorithmInteface(); }}
用戶端代碼
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(); Console.Read();}
優缺點
優點
提供了一種替代繼承的方法,而且既保持了繼承的優點(代碼重用)還比繼承更靈活(演算法獨立,可以任意擴充)。
避免程式中使用多重條件轉移語句,使系統更靈活,並易於擴充。
缺點
因為每個具體策略類都會產生一個新類,所以會增加系統需要維護的類的數量。
解決方案:Factory 方法