你瞭解的工廠模式可能有誤 原 薦

5月一個酷熱的中午,我跟剛來不久的小兄弟,小當閒聊起了公司用的的設計模式。

我侃侃而談道:“咱們公司,使用的設計模式不多,也就是 策略,門面,簡單工廠,工廠,單例,命令,組合,模板等。”

小當:“什麼是簡單工廠啊?,跟工廠模式有區別嗎?”

我一聽,便雙手交叉於胸前,略有深意的說:“你瞭解的工廠模式是什麼?”

小當非常流利的說:“將創建的對象方法,抽取到一個類中,根據類型不同創建相應的對象。”

我嘆了口氣:“小當,你瞭解的工廠模式有誤哦,這個是簡單工廠”

小當充滿疑惑的說:“那什麼是工廠模式,什麼又是簡單工廠呢?”

我喝了一口水,娓娓道來:“

簡單工廠不是設計模式,而是一種編程習慣。

將創建對象的方法,抽取到一個公共類中,根據類型不同創建相應的對象。

不屬於23種GOF設計模式之一。

就拿獲取算獎器的例子來說吧,PL3,DLT等都有自己的算獎器。簡單工廠實現方式如下:

package factory;
public class SimpleCalculatorFactoryDemo {
    public static abstract class Calculator{
        private String type;
        public Calculator(String type) {
            this.type = type;
        }
        public void calculate(){
            System.out.println(" This "+type+" calculate is done");
        }
    }
    public static class PL3Calculator extends Calculator{
        public PL3Calculator() {
            super("PL3");
        }
    }
    public static class DLTCalculator extends Calculator{
        public DLTCalculator() {
            super("DLT");
        }
    }

    public static class SimpleCalculatorFactory{
        public  Calculator createCalculator(String type){
            if ("PL3".equals(type)) { return new PL3Calculator(); }
            else if ("DLT".equals(type)){ return new DLTCalculator(); }
            return null;
        }
    }

    public static class PrizeTicketHandler{
        SimpleCalculatorFactory factory;
        public PrizeTicketHandler(SimpleCalculatorFactory factory){
            this.factory=factory;
        }
        public Calculator getCalculator(String type){
            return factory.createCalculator(type);
        }
    }
    public static void main(String[] args) {
        SimpleCalculatorFactoryDemo. SimpleCalculatorFactory factory=new SimpleCalculatorFactory();
        PrizeTicketHandler prizeTicketHandler=new PrizeTicketHandler(factory);
        prizeTicketHandler.getCalculator("DLT").calculate();
    }
}

其類圖如下:

我正準備往下說簡單工廠的缺點的時候,小當嚼着蘋果不耐煩的說:"這個你不用細說的,我早就爛熟於心了。"

抿了抿嘴,一笑說道:“那這種方式存在什麼問題?”

小當停止嚼蘋果,思考了10幾秒說:“每新增一個類,工廠中的if判斷語句也相應增加,對系統的維護和擴展非常不利。”

我點頭表示認可的說道:

“確實,隨着具體的產品類增加,簡單工廠的邏輯需要修改,逐漸變得不易擴展和維護,並沒有做的對修改關閉,對擴展開發。”

小當吃了一大口蘋果後,若有所思的說道:“咱們系統中可不是這樣寫的,獲取算獎器是分數字彩和競彩的。”

我喝了口水後,嘗試引導小當,問道:“你還記得咱們系統是如何實現的嗎?”

小當扔掉蘋果核,擦擦手說道:“ 當然,其實現大致如下 ”

(注意:工廠模式的實現)

package factory;
public class FactoryCalculatorDemo {
    public static abstract class Calculator{
        private String type;
        public Calculator(String type) {
            this.type = type;
        }
        public void calculate(){
            System.out.println(" This "+type+" calculate is done");
        }
    }
    public static class PL3Calculator extends Calculator {
        public PL3Calculator() {
            super("PL3");
        }
    }
    public static class DLTCalculator extends Calculator {
        public DLTCalculator() { super("DLT"); }
    }
    public static class BSKCalculator extends Calculator {
        public BSKCalculator() {
            super("BSK");
        }
    }
    public static class FTCalculator extends Calculator {
        public FTCalculator() {
            super("FT");
        }
    }

    public static abstract class CalculatorFactory{
        public abstract Calculator createCalculator(String type);
    }

    public static class NumberLotteryCalculatorFactory extends CalculatorFactory {
        @Override
            public Calculator createCalculator(String type){
                if ("PL3".equals(type))
                { return new PL3Calculator(); }
                else if ("DLT".equals(type))
                { return new DLTCalculator(); }
                return null;
            }
    }

    public static class JCCalculatorFactory extends CalculatorFactory {
        @Override
        public Calculator createCalculator(String type){
            if ("BSK".equals(type))
            { return new BSKCalculator(); }
            else if ("FT".equals(type))
            { return new FTCalculator(); }
            return null;
        }
    }

    public static void main(String[] args) {
        //調用者,知悉使用的子類
        CalculatorFactory calculatorFactory=new NumberLotteryCalculatorFactory();
        calculatorFactory.createCalculator("PL3").calculate();
        calculatorFactory=new JCCalculatorFactory();
        calculatorFactory.createCalculator("FT").calculate();
    }
}

其類圖如下:

我看後很欣慰他掌握的挺好,我可以放心的走了。隨後不等小當說話,強行總結說道:

“這個就是工廠模式了,定義了一個創建對象的接口,但由子類覺得要實例化的類是哪一個,即由NumberLotteryCalculatorFactory 和JCCalculatorFactory 決定實例化的類”。

小當搶着說:“NumberLotteryCalculatorFactory 和JCCalculatorFactory也實現了平行層級關係,若果有新加入的類,加入一個對應的工廠子類就好,不需要修改原來的代碼”。

“是的” 我點頭說道。

小當摸了摸下巴,又問道:“工廠模式瞭解了,那爲什麼系統中還會使用簡單工廠呢?”

我一笑說道:“咱們校驗器部分就是使用的簡單工廠,校驗器只有3個:注數,格式,金額,基本上不會變。所以使用簡單工廠就好,記住實現功能越簡單越好,Keep it Simple is best

總結:

工廠模式:定義了一個創建對象的接口,但由子類覺得要實例化的類是哪一個。

至於選擇具體選擇簡單工廠還是工廠模式,完全看業務需要,實現功能越簡單越好。

Keep it Simple is best。

                                                                                                            ---溫安適,20180525

寫在最後:

預計29號,就要離開這家公司了,這篇文章最後也道個別。這家公司給的工資不高,但是積累了很多經驗,無論是技術,還是管理,又提升了逆商,非常感謝,再見彩福達。

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