C#設計模式(1)——簡單工廠模式


1.什么是簡單工廠

  現實中的工廠負責生產產品,顧名思義,編程中的簡單工廠就是一個生產對象的類,它的主要作用是創建具體的產品類實例。我們以一個生產鼠標為例來分析簡單工廠的作用,鼠標有兩種:戴爾鼠標和惠普鼠標,代碼如下:

    //鼠標抽象類
    public abstract class Mouse
    {
        public abstract void Print();
    }


    //戴爾鼠標
    public class DellMouse : Mouse
    {
        public override void Print()
        {
            Console.WriteLine("生產了一個Dell鼠標!");
        }
    }

    //惠普鼠標
    public class HpMouse : Mouse
    {
        public override void Print()
        {
            Console.WriteLine("生產了一個惠普鼠標!");
        }
    }

客戶端代碼:

    class Program
    {
        static void Main(string[] args)
        {
            Mouse mouse1 = new DellMouse();
            Mouse mouse2 = new DellMouse();
            Mouse mouse3 = new DellMouse();
            Mouse mouse4 = new DellMouse();
            Mouse mouse5 = new DellMouse();
            mouse1.Print();
        }
    }

程序運行如下:

  我們可以看到程序運行沒有問題,通過new一個DellMouse我們可以創建一個戴爾的鼠標,這時有一個問題,如果我們不想要戴爾鼠標了,要全部生產惠普鼠標怎么辦呢?最簡單直接的方法就是把 new DellMouse全部替換成 new HpMouse 。如果我們的軟件中new了100個DellMouse實例呢?一個一個地去替換會是一個巨大的工作量,同時通過new的方式來創建戴爾鼠標的實例,會讓DellMouse類和客戶端產生強耦合關系,這時候使用簡單工廠就可以幫助我們降低耦合,減少工作量了。添加一個MouseFactory簡單工廠類,這個工廠類專門來創建Mouse的實例:

   /// <summary>
    /// 鼠標工廠類
    /// </summary>
    public class MouseFactory
    {
        private Mouse mouse = null;
        public Mouse CreateMouse(string brand)
        {
            switch (brand)
            {
                case "dell":
                    mouse = new DellMouse();
                    break;
                case "hp":
                    mouse = new HpMouse();
                    break;
                default:
                    break;
            }
            return mouse;
        }
    }

客戶端的代碼就可以改成:

    class Program
    {
        static void Main(string[] args)
        {
            //實例化一個工廠類
            MouseFactory mouseFactory = new MouseFactory();
            //通過工廠類創建鼠標
            Mouse mouse1 = mouseFactory.CreateMouse("dell");
            Mouse mouse2 = mouseFactory.CreateMouse("dell");
            Mouse mouse3 = mouseFactory.CreateMouse("dell");
            Mouse mouse4 = mouseFactory.CreateMouse("dell");
            Mouse mouse5 = mouseFactory.CreateMouse("dell");
            mouse1.Print();
            Console.ReadKey();
        }
    }

  運行程序結果一樣的,這樣做有什么好處呢?我們看到我們把以前的 new DellMouse() 替換成了  mouseFactory.Create("dell") ,客戶端和DellMouse的耦合變成了 客戶端<-->MouseFactory<-->DellMouse形式,有效降低了客戶端和DellMouse間的耦合。我們還用一個疑問,程序改成這樣的話,如果我們想把戴爾鼠標全部換成惠普鼠標,要把工廠類的參數"dell"換成"hp",不是還要改100次?任務量沒有降低呀!對於這個問題,我們可以把品牌名brand存放在一個地方,如配置文件中,這樣我們想切換鼠標品牌時就不用修改代碼,直接修改配置文件即可,如下:

配置文件:

  <appSettings>
    <add key="dbname" value="dell"/>
  </appSettings>

工廠類修改為:

    /// <summary>
    /// 鼠標工廠類
    /// </summary>
    public class MouseFactory
    {
       //從配置文件中讀取品牌
        private static readonly string brand = ConfigurationManager.AppSettings["brand"];
        private Mouse mouse = null;
        public Mouse CreateMouse()
        {
            switch (brand)
            {
                case "dell":
                    mouse = new DellMouse();
                    break;
                case "hp":
                    mouse = new HpMouse();
                    break;
                default:
                    break;
            }
            return mouse;
        }
    }

客戶端代碼就不用傳參數了,如下:

    class Program
    {
        static void Main(string[] args)
        {
            //實例化一個工廠類
            MouseFactory mouseFactory = new MouseFactory();
            //通過工廠類創建鼠標
            Mouse mouse1 = mouseFactory.CreateMouse();
            Mouse mouse2 = mouseFactory.CreateMouse();
            Mouse mouse3 = mouseFactory.CreateMouse();
            Mouse mouse4 = mouseFactory.CreateMouse();
            Mouse mouse5 = mouseFactory.CreateMouse();
            mouse1.Print();
            Console.ReadKey();
        }
    }

現在我們想把生產的鼠標都換成惠普鼠標,只需要將配置文件中的dell改成hp即可,修改配置文件后運行結果如下:

大功告成!這時有一個問題,如果我們想生產華碩鼠標怎么辦呢?除了添加一個繼承Mouse的AsusMouse類外,還要在MouseFactory中添加一段case 代碼。按照開閉原則,添加一個實現類沒什么問題,開閉原則中對添加開放;但是修改MouseFactory工廠類就違背了對修改閉合的原則了。后邊的工廠模式就是專門用來解決這個問題的。

2.小結

上邊例子的類圖:

簡單工廠的優點:

  1.簡單工廠可以有效地降低客戶端和具體對象的耦合,將new具體對象的任務交給了一個簡單工廠類

  2可以有效的進行代碼復用,如客戶端A和客戶端B都需要一個具體對象,客戶端A和客戶端B可以通過同一個簡單工廠來獲取具體類型的實例

簡單工廠的缺點:

  一定程度上違背了開閉原則,在新增產品時需要修改簡單工廠類

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM