設(shè)計模式之簡單工廠

工廠模式

工廠模式:顧名思義就是使得這個類的作用和工廠一樣,生產(chǎn)產(chǎn)品,在這里使用,我們就是生產(chǎn)類。工廠模式就是生產(chǎn)類,創(chuàng)建類的模式。

其在父類中提供一個創(chuàng)建對象的方法,允許子類決定實例化對象的類型。

代碼綁定著具體類會導(dǎo)致代碼更脆弱,更缺乏彈性,不易擴展,修改困難。

針對接口編程,可以隔離掉以后系統(tǒng)可能發(fā)生的一大堆改變,易于擴展。

用于處理改變,并幫助我們“找出會變化的方面,把它們從不變的部分分離出來”

Demo

image.png

比如現(xiàn)在有一個物流公司,之前業(yè)務(wù)很單一,只做陸上物流,隨著時間的推移,市場的變化,也有了海上物流,那么如何設(shè)計出一種實現(xiàn)方式來應(yīng)對這種在業(yè)務(wù)邏輯上的不確定性,如果后面在增加一種空中物流,那么將如何設(shè)計呢。

如何只有路上物流和海上物流,我們可以只在單獨的類中各自聲明下,后面通過if/eles方式來判斷是那個物流,從而去實現(xiàn)它即可。這樣做沒有問題,可以解決業(yè)務(wù)上面所面臨的問題,但是確不是軟件開發(fā)中最好的實現(xiàn)方式,如果你通過if/eles來實現(xiàn),那么它們的耦合度太高,后期如果陸上物流發(fā)生修改,會導(dǎo)致修改的地方過多,且不易于擴展。

簡單實現(xiàn)邏輯

    /// <summary>
    /// 海上物流
    /// </summary>
    public class AtSeaLogistics
    {
        /// <summary>
        /// 海上發(fā)貨
        /// </summary>
        public void SendSeaGoods(string goodName) 
        {
            Console.WriteLine("海上 Send:"+goodName);
        }
    }
    /// <summary>
    /// 陸地物流
    /// </summary>
    public class LandLogistics
    {
        /// <summary>
        /// 陸地發(fā)貨
        /// </summary>
        public void SendLandGoods(string goodName)
        {
            Console.WriteLine("陸地 Send:"+goodName);
        }
    }
        static void Main(string[] args)
        {
            int logisticsType = 0;                                      //默認(rèn)為陸地運輸
            Console.WriteLine("開始發(fā)貨");
            if (logisticsType==0)
            {
                LandLogistics land = new LandLogistics();
                land.SendLandGoods("Iphone 13");
            }
            else
            {
                AtSeaLogistics atSea = new AtSeaLogistics();
                atSea.SendSeaGoods("海魚");
            }
            Console.WriteLine("發(fā)貨完成");
            Console.ReadKey();
        }

運行后,由于是默認(rèn)陸地發(fā)貨,則調(diào)用陸地發(fā)貨模塊,進(jìn)行發(fā)貨。


結(jié)果

這其實是一種很簡單,也是我們目前寫簡單邏輯最最常用的方式,實現(xiàn)功能沒有問題,可是這種實現(xiàn)方式存在很大的隱患和不可擴展,如果后期在需要添加一種運輸方式,可能得需要在Main()方法中修改才行,運輸方式和物流的耦合性過高,且不易擴展。

下面是使用簡單工廠模式的實現(xiàn),通過接口去各自實現(xiàn),各自負(fù)責(zé)各自的事情,物流公司不需要知道去使用哪一種方式發(fā)貨,只需要將貨物交給發(fā)貨工廠,發(fā)貨工廠根據(jù)貨物自己來決定該使用哪一種方式發(fā)貨。

工廠模式

    public interface ISendInterface
    {
        void SendGoods(string goodName);
    }
    /// <summary>
    /// 陸地物流
    /// </summary>
    public class LandLogistics:ISendInterface
    {
        /// <summary>
        /// 陸地發(fā)貨
        /// </summary>
        public void SendGoods(string goodName)
        {
            Console.WriteLine("陸地 Send:" + goodName);            
        }

        ///// <summary>
        ///// 陸地發(fā)貨
        ///// </summary>
        //public void SendLandGoods(string goodName)
        //{
        //    Console.WriteLine("陸地 Send:"+goodName);
        //}
    }
    /// <summary>
    /// 海上物流
    /// </summary>
    public class AtSeaLogistics:ISendInterface
    {
         /// <summary>
        /// 海上發(fā)貨
        /// </summary>
        public void SendGoods(string goodName)
        {
            Console.WriteLine("海上 Send:" + goodName);            
        }

        //public void SendSeaGoods(string goodName) 
        //{
        //    Console.WriteLine("海上 Send:"+goodName);
        //}
    }
    /// <summary>
    /// 物流管理,主要用于發(fā)貨
    /// </summary>
    public class LogisticsStoreFactory
    {
        ISendInterface sendGood = null;
        public ISendInterface GetSendInterface(int type)
        {
            switch (type)
            {
                case 1:
                    sendGood = new LandLogistics();
                    break;
                case 2:
                    sendGood = new AtSeaLogistics();
                    break;
                default:
                    break;
            }
            return sendGood;
        }
    }

調(diào)用實現(xiàn)邏輯

            LogisticsStoreFactory logisticsStore = new LogisticsStoreFactory();
            //陸地運輸
            ISendInterface loadSend = logisticsStore.GetSendInterface(1);
            loadSend.SendGoods("Iphone 13");

            //海上運輸

            ISendInterface atSeaSend = logisticsStore.GetSendInterface(2);
            atSeaSend.SendGoods("海魚");

            Console.WriteLine("發(fā)貨完成");
            Console.ReadKey();

現(xiàn)在基本可以看出,簡單工廠在實現(xiàn)過程中,不需要關(guān)注去如何實現(xiàn)各自的運輸,只是通過LogisticsStoreFactory工廠類來獲取實現(xiàn),拿來即用就可以。這樣就實現(xiàn)了解耦,將調(diào)用和實現(xiàn)進(jìn)行了拆分,不需要過多關(guān)注它是如何實現(xiàn),只進(jìn)行使用即可。

適用場景

  • 在編碼過程中,無法預(yù)知對象類別和其具體依賴關(guān)系時,可使用簡單工廠。
  • 將創(chuàng)建和實現(xiàn)分離,在不影響其它產(chǎn)品的時候,可自主創(chuàng)建,低耦合,易擴展。

實現(xiàn)方式

  • 定義各個產(chǎn)品類,讓其每個類各自干各自的工作,互相不干擾。
  • 先聲明一個共有的接口,讓所有的產(chǎn)品都實現(xiàn)這個接口。
  • 創(chuàng)建一個空的工廠類,讓其擁有獲取產(chǎn)品的能力,且返回這個共有的接口。
  • 在創(chuàng)建者代碼中找到對于產(chǎn)品構(gòu)造函數(shù)的引用,將其修改為工廠方法的引用,同時將創(chuàng)建產(chǎn)品的代碼移植到工廠方法中。

小寄語

一個人的奮斗,像懷孕一樣,日子久了,總會被看出來的。

人生短暫,我不想去追求自己看不見的,我只想抓住我能看的見的。

我是阿輝,感謝您的閱讀,如果對你有幫助,麻煩點贊,轉(zhuǎn)發(fā) 謝謝。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容