《C#設計模式》 工廠三兄弟之 【簡單工廠模式】,【工廠方法模式】,【抽象工廠模式】

《C#設計模式》 三種工廠設計模式

  1. 【簡單工廠模式】

  2. 【工廠方法模式】

  3. 【抽象工廠模式】

第一種:簡單工廠模式

一:【簡單工廠模式】

簡單工廠模式概念(Simple Factory Pattern):定義一個工廠類,它可以根據參數的不同返回不同類的實例,被創建的實例通常都具有共同的父類。因爲在簡單工廠模式中用於創建實例的方法是靜態(static)方法,因此簡單工廠模式又被稱爲靜態工廠方法(Static Factory Method)模式,它屬於類創建型模式。

二: 案例分析

使用簡單工廠模式設計一個可以創建不同幾何形狀(如圓形、方形和三角形等)的繪圖工具,每個幾何圖形都具有繪製draw()和擦除erase()兩個方法;

 首先定義一個接口類;包含兩個方法;繪製;擦除;


    interface Draws
    {
        //繪製圖形
        void draw();
        //擦除圖形
        void erase();
    }

再在某個具體產品類繼承這個Draws接口;以下爲三種圖形實現方式;

  //==============================================================
    //  作者:zhoupei
    //  時間:2019/2/18 14:12:11
    //  文件名:Circular
    //  版本:V1.0.1  
    //  說明:圓形具體產品類     
    //==============================================================
    class Circular : Draws
    {
        public void draw()
        {
            Console.WriteLine("繪製圓形圖形");
        }
        public void erase()
        {
            Console.WriteLine("擦除圓形圖形");
        }

    }


 class Rectangle : Draws
    {
        //繪製矩形
        public void draw()
        {
            Console.WriteLine("繪製矩形圖形");
        }
        //擦除矩形
        public void erase()
        {
            Console.WriteLine("擦除矩形圖形");
        }
    }

  class Triangle: Draws
    {
        public void draw()
        {
            Console.WriteLine("繪製三角形圖形");
        }

        public void erase()
        {
            Console.WriteLine("擦除三角形圖形");
        }
    }

再寫個圖形處理工廠類,靜態工廠方法;

 class FigureFactory
    {
        //靜態工廠方法
        public static Draws Getfigure(string figtype)
        {
            Draws dws = null;
            switch (figtype.ToLower())
            {
                case "rectangle":
                    dws = new Rectangle();
                    break;
                case "triangle":
                    dws = new Rectangle();
                    break;
                case "circular":
                    dws = new Rectangle();
                    break;
                default:
                    dws = null;
                    break;
            }
            return dws;
        }
    }

客戶端調用方法,這裏根據讀取全局配置文件的方式來獲取路徑;

添加app.config文件;配置路徑;

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="figureType" value="Circular"/>  //傳入圓形
  </appSettings>
</configuration>

Main函數調用方法;

 static void Main(string[] args)
        {
            Draws dw;
            string figurestr = ConfigurationSettings.AppSettings["figureType"];
            dw = FigureFactory.Getfigure(figurestr);
            dw.draw();//繪製 - 圓形
            dw.erase();//擦除 - 圓形
            Console.ReadLine();
        }

優缺點總結:

 1. 主要優點

       簡單工廠模式的主要優點如下:

       (1) 工廠類包含必要的判斷邏輯,可以決定在什麼時候創建哪一個產品類的實例,客戶端可以免除直接創建產品對象的職責,而僅僅“消費”產品,簡單工廠模式實現了對象創建和使用的分離。

       (2) 客戶端無須知道所創建的具體產品類的類名,只需要知道具體產品類所對應的參數即可,對於一些複雜的類名,通過簡單工廠模式可以在一定程度減少使用者的記憶量。

       (3) 通過引入配置文件,可以在不修改任何客戶端代碼的情況下更換和增加新的具體產品類,在一定程度上提高了系統的靈活性。

         2. 主要缺點

       簡單工廠模式的主要缺點如下:

       (1) 由於工廠類集中了所有產品的創建邏輯,職責過重,一旦不能正常工作,整個系統都要受到影響。

       (2) 使用簡單工廠模式勢必會增加系統中類的個數(引入了新的工廠類),增加了系統的複雜度和理解難度。

       (3) 系統擴展困難,一旦添加新產品就不得不修改工廠邏輯,在產品類型較多時,有可能造成工廠邏輯過於複雜,不利於系統的擴展和維護。

       (4) 簡單工廠模式由於使用了靜態工廠方法,造成工廠角色無法形成基於繼承的等級結構。
 

 

第二種:工廠方法模式

工廠方法模式概念:工廠方法模式(Factory Method Pattern):定義一個用於創建對象的接口,讓子類決定將哪一個類實例化。工廠方法模式讓一個類的實例化延遲到其子類。工廠方法模式又簡稱爲工廠模式(Factory Pattern),又可稱作虛擬構造器模式(Virtual Constructor Pattern)或多態工廠模式(Polymorphic Factory Pattern)。工廠方法模式是一種類創建型模式。

案例分析:使用工廠方法模式設計一個程序來讀取各種不同類型的圖片格式,針對每一種圖片格式都設計一個圖片讀取器,如GIF圖片讀取器用於讀取GIF格式的圖片、JPG圖片讀取器用於讀取JPG格式的圖片。需充分考慮系統的靈活性和可擴展性。

首先定義圖片接口  即抽象產品類;代碼如下!

 /// <summary>
    /// 圖片處理接口 
    /// 抽象產品:它是定義產品的接口,是工廠方法模式所創建對象的超類型,也就是產品對象的公共父類。
    /// </summary>
    interface Imager
    {
        void GetImages();
    }

然後定義抽象工工廠類; 代碼如下!

 interface ImagerFactory
    {
        Imager GetImagelist(); //抽象產品工廠類
    }

現在客戶需求裏要分別讀取處理JPG格式的圖片跟GIF格式的圖片;

具體產品類

    //==============================================================
    //  作者:zhoupei
    //  時間:2019/2/18 11:45:23
    //  文件名:GifImg
    //  版本:V1.0.1  
    //  說明:Gif圖片 - 具體產品類    
    //==============================================================
    class GifImg : Imager
    {
        public void GetImages()
        {
            Console.WriteLine("讀取GIF圖片。");
        }
    }

    class JpgImg : Imager
    {
        public void GetImages()
        {
            Console.WriteLine("讀取Jpg圖片。");
        }
    }

 

具體產品工廠

 //==============================================================
    //  作者:zhoupei
    //  時間:2019/2/18 11:46:05
    //  文件名:GifImgFactory
    //  版本:V1.0.1  
    //  說明:產品具體工廠 
    //==============================================================
    class GifImgFactory : ImagerFactory  //繼承自抽象產品類
    {
        public Imager GetImagelist()
        {
            Imager im = new GifImg();
            return im;
        }
    } 
    


    class JpgImgFactory : ImagerFactory
    {
        public Imager GetImagelist()
        {
            Imager im = new JpgImg();
            return im;
        }
    }

客戶端Main()調用: 方式跟以上一樣

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="imageFactory"  value="FactoryMethod.JpgImgFactory"/>
  </appSettings>
</configuration>
  static void Main(string[] args)
        {
            ImagerFactory ifc;
            Imager img;
            string factStr = ConfigurationManager.AppSettings["imageFactory"];
            ifc = (JpgImgFactory)Assembly.Load("FactoryMethod").CreateInstance(factStr);
            img = ifc.GetImagelist();
            img.GetImages();

            Console.ReadLine();
        }

工廠方法模式總結:

 1. 主要優點

       工廠方法模式的主要優點如下:

       (1) 在工廠方法模式中,工廠方法用來創建客戶所需要的產品,同時還向客戶隱藏了哪種具體產品類將被實例化這一細節,用戶只需要關心所需產品對應的工廠,無須關心創建細節,甚至無須知道具體產品類的類名。

       (2) 基於工廠角色和產品角色的多態性設計是工廠方法模式的關鍵。它能夠讓工廠可以自主確定創建何種產品對象,而如何創建這個對象的細節則完全封裝在具體工廠內部。工廠方法模式之所以又被稱爲多態工廠模式,就正是因爲所有的具體工廠類都具有同一抽象父類。

       (3) 使用工廠方法模式的另一個優點是在系統中加入新產品時,無須修改抽象工廠和抽象產品提供的接口,無須修改客戶端,也無須修改其他的具體工廠和具體產品,而只要添加一個具體工廠和具體產品就可以了,這樣,系統的可擴展性也就變得非常好,完全符合“開閉原則”。

 

      2. 主要缺點

     工廠方法模式的主要缺點如下:

      (1) 在添加新產品時,需要編寫新的具體產品類,而且還要提供與之對應的具體工廠類,系統中類的個數將成對增加,在一定程度上增加了系統的複雜度,有更多的類需要編譯和運行,會給系統帶來一些額外的開銷。

      (2) 由於考慮到系統的可擴展性,需要引入抽象層,在客戶端代碼中均使用抽象層進行定義,增加了系統的抽象性和理解難度,且在實現時可能需要用到DOM、反射等技術,增加了系統的實現難度。

 

第三中:抽象工廠模式

抽象工廠模式概述:提供一個創建一系列相關或相互依賴對象的接口,而無須指定它們具體的類。抽象工廠模式又稱爲Kit模式,它是一種對象創建型模式。

案例分析:某個軟件公司欲推出一款新的手機遊戲軟件,該軟件能夠支持Symbian、Android和Windows Mobile等多個智能手機操作系統平臺,針對不同的手機操作系統,該遊戲軟件提供了不同的遊戲操作控制(OperationController)類和遊戲界面控制(InterfaceController)類,並提供相應的工廠類來封裝這些類的初始化過程。軟件要求具有較好的擴展性以支持新的操作系統平臺,爲了滿足上述需求,試採用抽象工廠模式對其進行設計。

具體實現:

//抽象產品類
  interface Android
    {
        void Description();
    }

  interface Apple
    {
        void Description();
    } 

  interface ASymbian
    {
        void Description();
    }

抽象工廠類:

/// <summary>
    /// 遊戲支持系統抽象工廠
    /// </summary>
    interface GameFactory
    {
        ASymbian CanRunonSymbian();
        Android CanRunonAndroid();
        Apple CanRunonApple();
    }

具體產品類

    //==============================================================
    //  作者:zhoupei
    //  時間:2019/2/18 16:08:35
    //  文件名:InterfaceControllerOnAndroid
    //  版本:V1.0.1  
    //  說明:安卓系統支持InterfaceControllerOnAndroid
    //==============================================================
    class InterfaceControllerOnAndroid : Android
    {
        public void Description()
        {
            Console.WriteLine("安卓系統支持InterfaceControllerOnAndroid遊戲操作控制");
        }
    }

    class InterfaceControllerOnApple : Apple
    {
        public void Description()
        {
            Console.WriteLine("蘋果支持 InterfaceController遊戲操作控制");
        }
    }

    class InterfaceControllerOnSymbian :ASymbian
    {
        public void Description()
        {
            Console.WriteLine("塞班系統支持InterfaceController遊戲操作控制");
        }
    }





    //==============================================================
    //  作者:zhoupei
    //  時間:2019/2/18 16:07:45
    //  文件名:OperationControllerOnAndroid
    //  版本:V1.0.1  
    //  說明:支持OperationController 
    //==============================================================
    class OperationControllerOnAndroid :Android
    {
        public void Description()
        {
            Console.WriteLine("安卓系統支持OperationControllerOnAndroid遊戲操作控制");
        }
    }

    class OperationControllerOnApple : Apple
    {
        public void Description()
        {
            Console.WriteLine("蘋果系統支持OperationController遊戲操作控制");
        }
    } 

    class OperationControllerOnSymbian : ASymbian
    {
        public void Description()
        {
            Console.WriteLine("塞班系統支持OperationController遊戲操作控制");
        }
    }

具體工廠類:

    //==============================================================
    //  作者:zhoupei
    //  時間:2019/2/18 16:10:59
    //  文件名:B_InterfaceController
    //  版本:V1.0.1  
    //  說明:
    //==============================================================
    class B_InterfaceController : GameFactory
    {
        public Android CanRunonAndroid()
        {
            return new InterfaceControllerOnAndroid();
        }

        public Apple CanRunonApple()
        {
            return new InterfaceControllerOnApple();
        }

        public ASymbian CanRunonSymbian()
        {
            return new InterfaceControllerOnSymbian();
        }

    }


    class B_OperationController : GameFactory
    {
        public Android CanRunonAndroid()
        {
            return new OperationControllerOnAndroid();
        }

        public Apple CanRunonApple()
        {
            return new OperationControllerOnApple();
        }

        public ASymbian CanRunonSymbian()
        {
            return new OperationControllerOnSymbian();
        }
    }

抽象工廠模式總結

    1. 主要優點

       抽象工廠模式的主要優點如下:

       (1) 抽象工廠模式隔離了具體類的生成,使得客戶並不需要知道什麼被創建。由於這種隔離,更換一個具體工廠就變得相對容易,所有的具體工廠都實現了抽象工廠中定義的那些公共接口,因此只需改變具體工廠的實例,就可以在某種程度上改變整個軟件系統的行爲。

       (2) 當一個產品族中的多個對象被設計成一起工作時,它能夠保證客戶端始終只使用同一個產品族中的對象。

       (3) 增加新的產品族很方便,無須修改已有系統,符合“開閉原則”。

 

       2. 主要缺點

       抽象工廠模式的主要缺點如下:

       增加新的產品等級結構麻煩,需要對原有系統進行較大的修改,甚至需要修改抽象層代碼,這顯然會帶來較大的不便,違背了“開閉原則”。

 

 

 

三種工廠方式學習總結完畢,歡迎指正,討論指教;

學習來自我的大學老師《C#設計模式》,感謝恩師;

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章