前言
上一篇我們介紹了單例模式,今天給大家講一個比較簡單的模式——工廠模式(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、在增加需求的時候,增加產品的時候僅需要新增一個工廠類及產品類即可,不需要對原來的代碼進行修改。可輕易的擴展。
(三)缺點
在增加產品的時候,額外的增加了工廠類及產品類。增加一個產品增加兩個類。在一定程度上增加了系統的復雜度。同時也增強了類之間的依賴性。這也就是其中不好的問題
總結
每一個設計模式都有對應的使用場合,切勿濫用。在我們學習設計模式的同時,我們也需要以其原主要則作為基准學習。萬萬不能違背原則。在設計模式——工廠模式中,將創建對象的任務委托給其工廠子類、延遲執行。解決了系統難於擴展的問題,同時也減少了具體類與對象之間的耦合性。也實現了開放擴展封閉修改的原則。
這個社會是存在不公平的,不要抱怨,因為沒有用!人總是在反省中進步的!
歡迎大家掃描下方二維碼,和我一起踏上設計模式的闖關之路吧!