二級小兵——工廠模式(Factory Method)
前言
上一篇我們介紹了單例模式,今天給大家講一個比較簡單的模式——工廠模式(Factory Method),工廠模式又是什麼呢?顧名思義,工廠——生產製造東西的地方。那麼應用在程式當中該如何使用、並且又起到什麼效果呢?以至於為什麼用工廠模式呢?
之前我們說的OCP原則(開放封閉原則),對擴充套件開放,對修改封閉這一原則。在工廠模式中有極好的體現,對物件及類進行極好的封裝。使其減少程式碼之間的耦合性。更具有擴充套件性。
工廠模式介紹
一、來由
在我們程式設計過程當中,總會面臨一些類的建立以及物件的建立,但是由於需求而不斷變動(增加或者修改),導致物件的變化。這時怎麼處理這個問題呢?
工廠模式提供的一種封裝機制,隔離出了那些易變動的物件。這個時候需求的變動不再影響之前的物件的變動了。
二、意圖
定義一個用於建立物件的介面,讓子類決定例項化哪一個類。FactoryMethod使一個類的例項化延遲到其子類。
三、案例圖
工廠模式中由以下部分組成:
(1)、抽象工廠(Creator): 複製定義工廠所需的基本規則,其他任何具體工廠都得繼承此抽象工廠
(2)、具體工廠(Concrete_Creator):繼承抽象工廠,實現其定義的方法,以此來建立具體的產品
(3)、抽象產品(Product):複製定義產品的基本方法及規則,所有具體產品都得基礎此抽象產品類
(4)、具體產品(Concrete_Product):繼承抽象產品,實現其定義抽象方法,由具體工廠建立,兩者是一一對應的關係。
四、工廠模式程式碼實現
這裡我們通過一個事例來介紹工廠模式的規則及用法。在工廠模式中,定義抽象工廠,然後其具體工廠繼承實現其抽象方法呼叫繼承了抽象產品類的具體產品來建立產品。
下面我們就手機產品的製造來看看下面的事例吧:
namespace ConsoleApp4 { public class Factory_Method_Pattern { } #region 產品 ========================= /// <summary> /// 抽象手機產品類 /// </summary> public abstract class Phone { public abstract string Create(); } /// <summary> /// 具體華為手機產品類 /// </summary> public class Huawei : Phone { /// <summary> /// 實現抽象方法 /// </summary> /// <returns></returns> public override string Create() { return "華為一號現世"; } } /// <summary> /// 具體小米手機產品類 /// </summary> public class Xiaomi : Phone { /// <summary> /// 實現抽象方法 /// </summary> /// <returns></returns> public override string Create() { return "小米一號現世"; } } #endregion #region 工廠========================= /// <summary> /// 抽象工廠類 /// </summary> public abstract class Factory { /// <summary> /// 抽象工廠類的方法,建立呼叫產品 /// </summary> /// <returns></returns> public abstract Phone CreatePhone(); } /// <summary> /// 具體華為工廠類,繼承抽象工廠類 /// </summary> public class HuaweiFactory : Factory { /// <summary> /// 實現繼承方法 /// </summary> /// <returns></returns> public override Phone CreatePhone() { return new Huawei(); } } /// <summary> /// 具體小米工廠類,繼承抽象工廠類 /// </summary> public class XiaomiFactory : Factory { /// <summary> /// 實現繼承方法 /// </summary> /// <returns></returns> public override Phone CreatePhone() { return new Xiaomi(); } } #endregion }
class Program { static void Main(string[] args) { //初始化工廠 Factory huaweiFactory = new HuaweiFactory(); //生產具體的華為手機 var result=huaweiFactory.CreatePhone(); //華為手機現世 var answer = result.Create(); Console.WriteLine(answer); Factory xiaomiFactory = new XiaomiFactory(); result = xiaomiFactory.CreatePhone(); answer = result.Create(); Console.WriteLine(answer); Console.ReadLine(); } }
在上述事例中,同樣是先把手機抽象出一個抽象類,手機當然也不是憑空出現的。所以需要再抽象一個工廠類。工廠類派生子類不同的手機廠商類。同樣手機也派生了不一樣的品牌。手機廠商類再對應手機品牌去生產相應的手機。這時我們需要增加一個手機手機品牌,我們不需要去修改工廠類及產品類。我們另外新增即可。完全不影響其原來的執行。比如我們需要新增魅族手機。
#region 新增魅族手機 ================ /// <summary> /// 新增魅族工廠類 /// </summary> public class MeizuFactory : Factory { public override Phone CreatePhone() { return new Meizu(); } } /// <summary> /// 新增具體魅族手機產品類 /// </summary> public class Meizu : Phone { public override string Create() { return "魅族一號現世"; } } #endregion
在客戶端呼叫時增加以下呼叫就可以了
Factory meizuFactory = new MeizuFactory(); result = meizuFactory.CreatePhone(); answer = result.Create(); Console.WriteLine(answer);
使用場景及優缺點
在此模式中,將所有要建立的具體物件的工作都延遲放在了子類中去實現,實現了一種擴充套件的策略。與OCP原則相對應。
工廠模式主要針對解決的是”單個物件”的問題。隔離類的物件的使用者與具體型別之間的耦合關係。去實現了一定程度的解耦。
(一)使用場景
1、當用戶不需要知道產品的類名的時候或者不關心如何建立的時候。我們只需要知道建立它的具體工廠的時候。
2、將建立物件的任務委託給多個工廠中的一個,客戶端使用的時候無需關心是哪一個建立產品。當需要動態指定。
(二)優點
1、在程式設計方法中,客戶端呼叫不需要知道產品的具體工廠,也不需要關心如何建立的。
2、在增加需求的時候,增加產品的時候僅需要新增一個工廠類及產品類即可,不需要對原來的程式碼進行修改。可輕易的擴充套件。
(三)缺點
在增加產品的時候,額外的增加了工廠類及產品類。增加一個產品增加兩個類。在一定程度上增加了系統的複雜度。同時也增強了類之間的依賴性。這也就是其中不好的問題
總結
每一個設計模式都有對應的使用場合,切勿濫用。在我們學習設計模式的同時,我們也需要以其原主要則作為基準學習。萬萬不能違背原則。在設計模式——工廠模式中,將建立物件的任務委託給其工廠子類、延遲執行。解決了系統難於擴充套件的問題,同時也減少了具體類與物件之間的耦合性。也實現了開放擴充套件封閉修改的原則。
這個社會是存在不公平的,不要抱怨,因為沒有用!人總是在反省中進步的!
C#設計模式系列目錄
歡迎大家掃描下方二維碼,和我一起踏上設計模式的闖關之路吧!
&n