C#設計模式(3)——工廠方法模式

1、引言

  在簡單工廠模式中講到簡單工廠模式的缺點,有一點是——簡單工廠模式系統難以擴展,一旦添加新產品就不得不修改簡單工廠方法,這樣就會形成簡單工廠的實現邏輯過於複雜,然而本專題介紹的工廠方法模式能夠解決簡單工廠模式中存在的這個問題,下面就具體看看工廠模式是如何解決該問題的。
html

2、工廠方法模式的實現

  工廠方法模式之因此能夠解決簡單工廠的模式,是由於它的實現把具體產品的建立推遲到子類中,此時工廠類再也不負責全部產品的建立,而只是給出具體工廠必須實現的接口,這樣工廠方法模式就能夠容許系統不修改工廠類邏輯的狀況下來添加新產品,這樣也就克服了簡單工廠模式中缺點。下面看下工廠模式的具體實現代碼(這裏仍是以簡單工廠模式中點菜的例子來實現):編程

namespace 設計模式之工廠方法模式
{
    /// <summary>
    /// 菜抽象類
    /// </summary>
    public abstract class Food
    {
        // 輸出點了什麼菜
        public abstract void Print();
    }
    /// <summary>
    /// 西紅柿炒雞蛋這道菜
    /// </summary>
    public class TomatoScrambledEggs : Food
    {
        public override void Print()
        {
            Console.WriteLine("西紅柿炒蛋好了!");
        }
    }
    /// <summary>
    /// 土豆肉絲這道菜
    /// </summary>
    public class ShreddedPorkWithPotatoes : Food
    {
        public override void Print()
        {
            Console.WriteLine("土豆肉絲好了");
        }
    }
    /// <summary>
    /// 抽象工廠類
    /// </summary>
    public abstract class Creator
    {
        // 工廠方法
        public abstract Food CreateFoddFactory();
    }
    /// <summary>
    /// 西紅柿炒蛋工廠類
    /// </summary>
    public class TomatoScrambledEggsFactory:Creator
    {
        /// <summary>
        /// 負責建立西紅柿炒蛋這道菜
        /// </summary>
        /// <returns></returns>
        public override Food CreateFoddFactory()
        {
            return new TomatoScrambledEggs();
        }
    }
    /// <summary>
    /// 土豆肉絲工廠類
    /// </summary>
    public class ShreddedPorkWithPotatoesFactory:Creator
    {
        /// <summary>
        /// 負責建立土豆肉絲這道菜
        /// </summary>
        /// <returns></returns>
        public override Food CreateFoddFactory()
        {
            return new ShreddedPorkWithPotatoes();
        }
    }
    /// <summary>
    /// 客戶端調用
    /// </summary>
    class Client
    {
        static void Main(string[] args)
        {
            // 初始化作菜的兩個工廠()
            Creator shreddedPorkWithPotatoesFactory = new ShreddedPorkWithPotatoesFactory();
            Creator tomatoScrambledEggsFactory = new TomatoScrambledEggsFactory();
            // 開始作西紅柿炒蛋
            Food tomatoScrambleEggs = tomatoScrambledEggsFactory.CreateFoddFactory();
            tomatoScrambleEggs.Print();
            //開始作土豆肉絲
            Food shreddedPorkWithPotatoes = shreddedPorkWithPotatoesFactory.CreateFoddFactory();
            shreddedPorkWithPotatoes.Print();
            Console.Read();
        }
    } 
}

使用工廠方法實現的系統,若是系統須要添加新產品時,咱們能夠利用多態性來完成系統的擴展,對於抽象工廠類和具體工廠中的代碼都不須要作任何改動。例如,咱們咱們還想點一個「肉末茄子」,此時咱們只須要定義一個肉末茄子具體工廠類肉末茄子類就能夠。而不用像簡單工廠模式中那樣去修改工廠類中的實現(具體指添加case語句)。具體代碼爲:c#

/// <summary>
    /// 肉末茄子這道菜
    /// </summary>
    public class MincedMeatEggplant : Food
    {
        /// <summary>
        /// 重寫抽象類中的方法
        /// </summary>
        public override void Print()
        {
            Console.WriteLine("肉末茄子好了");
        }
    }
 /// <summary>
    /// 肉末茄子工廠類,負責建立肉末茄子這道菜
    /// </summary>
    public class MincedMeatEggplantFactory : Creator
    {
        /// <summary>
        /// 負責建立肉末茄子這道菜
        /// </summary>
        /// <returns></returns>
        public override Food CreateFoddFactory()
        {
            return new MincedMeatEggplant();
        }
    }
    /// <summary>
    /// 客戶端調用
    /// </summary>
    class Client
    {
        static void Main(string[] args)
        {
                   
            // 若是客戶又想點肉末茄子了
            // 再另外初始化一個肉末茄子工廠
            Creator minceMeatEggplantFactor = new MincedMeatEggplantFactory();
            // 利用肉末茄子工廠來建立肉末茄子這道菜
            Food minceMeatEggplant = minceMeatEggplantFactor.CreateFoddFactory();
            minceMeatEggplant.Print();
            Console.Read();
        }
    }

3、工廠方法模式的UML圖

講解完工廠模式的具體實現以後,讓咱們看下工廠模式中各種之間的UML圖:設計模式

從UML圖能夠看出,在工廠方法模式中,工廠類與具體產品類具備平行的等級結構,它們之間是一一對應的。針對UML圖的解釋以下:ide

Creator類:充當抽象工廠角色,任何具體工廠都必須繼承該抽象類spa

TomatoScrambledEggsFactory和ShreddedPorkWithPotatoesFactory類:充當具體工廠角色,用來建立具體產品.net

Food類:充當抽象產品角色,具體產品的抽象類。任何具體產品都應該繼承該類設計

TomatoScrambledEggs和ShreddedPorkWithPotatoes類:充當具體產品角色,實現抽象產品類對定義的抽象方法,由具體工廠類建立,它們之間有一一對應的關係。xml

4、.NET中實現了工廠方法的類

.NET 類庫中也有不少實現了工廠方法的類,例如Asp.net中,處理程序對象是具體用來處理請求,當咱們請求一個*.aspx的文件時,此時會映射到System.Web.UI.PageHandlerFactory類上進行處理,而對*.ashx的請求將映射到System.Web.UI.SimpleHandlerFactory類中(這兩個類都是繼承於IHttpHandlerFactory接口的),關於這點說明咱們能夠在「C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\Web.Config」文件中找到相關定義,具體定義以下:htm

<httpHandlers>
<add path="*.axd" verb="*" type="System.Web.HttpNotFoundHandler" validate="True" />
            <add path="*.aspx" verb="*" type="System.Web.UI.PageHandlerFactory" validate="True" />
            <add path="*.ashx" verb="*" type="System.Web.UI.SimpleHandlerFactory" validate="True" />
</httpHandlers>

下面咱們就具體看下工廠方法模式在Asp.net中是如何實現的,若是對一個Index.aspx頁面發出請求時,將會調用PageHandlerFactory中GetHandler方法來建立一個Index.aspx對象,它們之間的類圖關係以下:

5、總結

工廠方法模式經過面向對象編程中的多態性來將對象的建立延遲到具體工廠中,從而解決了簡單工廠模式中存在的問題,也很好地符合了開放封閉原則(即對擴展開發,對修改封閉)。

相關文章
相關標籤/搜索