前言:
簡單工廠模式和策略模式是大部分程序員,在學習設計模式時接觸得最早,或在工作實踐中也是用得相對比較多的兩個設計模式。
一個是創建型,另一個是行為型,然而兩種不同類型的模式,在某些地方也有一絲的相似之處,同時在某種場景下結合使用,能起到特別好的效果。
問題:
我覺得簡單工廠模式和策略模式很相似。怎么相似?都是三個業務子類繼承抽象父類,通過傳入參數到容器類(工廠模式的factory類,策略模式的Content類),選擇對應的類進行行為操作。
其實,UML圖的確從外形上看沒多大區別,但是,本質卻是大大不同。
簡單工廠模式
上面提到過,簡單工廠模式是創建型模式,創建型模式顧名思義,也就是說在創建對象的時候,遇到了瓶頸才會選擇的設計模式。那么該什么情況使用呢。
簡單工廠模式的實質是由一個工廠類根據傳入的參數,動態決定應該創建並且返回哪一個產品類(這些產品類繼承自一個父類或接口)的實例。
那么也就是說:
1、有已知的產品類
2、你無法准確的知道編譯哪個產品類
3、需要在運行時決定創建哪個產品類
4、產品類不多
很明顯看出,在創建對象上的靈活性高,但是工廠類只能創建可能會使用到的產品類,假如新添了產品類就得修改工廠類,這樣就會違反開閉原則。
策略模式
策略模式是行為型模式,它定義了一系列的算法,並將每一個算法封裝起來,而且使它們還可以相互替換。策略模式讓算法獨立於使用它的客戶而獨立變化。
在一段代碼里,使用了邏輯控制(if-else,swich-case)來決定算法,算法有相似的方法和函數,就可以選擇策略模式。
那么也就是說:
1、某方法里有多個條件語句,條件語句代碼塊里有許多行為過程。
2、其算法能封裝到策略類
2、算法隨意切換
3、算法與客戶端隔離
這樣一來,通過選擇對應的策略類,作為參數傳到Content類里,在運行時配置對應的算法。
區別總結
從上面的描述總結出,在運行時,兩者都是通過傳入參數進行配置,簡單工廠模式則是選擇創建出需要的對象,而策略模式則是配置出需要的行為算法。一個是對象創建,另一個是行為算法的替換。
結合
下面有一段策略模式的代碼。
using System; using System.Net.Configuration; namespace StrategyWithFactory { class Program { static void Main(string[] args) { Strategy strategyContent = null; //偽代碼。獲取輸入算法類型 EStrategy inputType = RequestInput(); if (inputType == EStrategy.A) { new Content(new StrategyA()).ContentInterface(); } else if (inputType == EStrategy.B) { new Content(new StrategyB()).ContentInterface(); } else if (inputType == EStrategy.C) { new Content(new StrategyC()).ContentInterface(); } } } //算法抽象類 abstract class Strategy { public abstract void AlfoeirhmInterface(); } //A算法類 class StrategyA : Strategy { public override void AlfoeirhmInterface() { Console.WriteLine("this is the StrategyA"); } } //B算法類 class StrategyB : Strategy { public override void AlfoeirhmInterface() { Console.WriteLine("this is the StrategyB"); } } //B算法類 class StrategyC : Strategy { public override void AlfoeirhmInterface() { Console.WriteLine("this is the StrategyC"); } } //上下文類 class Content { private readonly Strategy _strategy; public Content(Strategy strategy) { _strategy = strategy; } public void ContentInterface() { _strategy.AlfoeirhmInterface(); } } //算法枚舉 enum EStrategy { A = 1, B = 2, C = 3 } }
上面的代碼是策略模式的原型,假如Main函數是客戶端,那么以后每加一個算法,都得在客戶端修改一次,添加一個else if,引起了不必要的麻煩。那么,現在的情況,首先我們知道已有的ABC三種算法,但是我們又不確定運行時使用哪種算法,同時為了讓客戶端和業務邏輯代碼隔離開,於是,我們可以將客戶端的創建算法類的業務邏輯轉移到Cotent類,並添加一個創建算法工廠的方法。
using System; namespace StrategyWithFactory { class Program { static void Main(string[] args) { //偽代碼。獲取輸入算法類型 EStrategy inputType = RequestInput(); new Content(inputType).ContentInterface(); } } //上下文類 class Content { private readonly Strategy _strategy; public Content(EStrategy eStrategy) { _strategy = CreateFactory(eStrategy); } public Strategy CreateFactory(EStrategy eStrategy) { Strategy strategy = null; switch (eStrategy) { case EStrategy.A: strategy = new StrategyA(); break; case EStrategy.B: strategy = new StrategyB(); break; case EStrategy.C: strategy = new StrategyC(); break; } return strategy; } public void ContentInterface() { _strategy.AlfoeirhmInterface(); } } }
那么,策略和簡單工廠的結合應用就實現了。