工廠方法模式(五)

工廠方法模式:定義一個用於創建對象的接口,讓子類決定實例化哪一個類。工廠方法使一個類的實例化延遲到其子類。

之前寫過一篇簡單工廠模式,其中有一個計算器的例子,那麼工廠方法模式和簡單工廠模式有什麼區別呢?

簡單工廠VS工廠方法:

在簡單工廠模式中,如果要增加一個功能需要修改工廠類,違背了開放-封閉原則,工廠方法模式在簡單工廠模式上新增加了一個工廠,用來生產簡單工廠類,這樣整個工廠和產品體系都沒有變化,只有擴展的變化,這樣就符合開放-封閉原則了。

簡單工廠模式的最大優點在於工廠類中包含了必要的邏輯判斷,根據客戶端選擇條件動態實例化相關的類,對於客戶端來說,去除了與具體產品的依賴。

比如在簡單工廠模式——計算器中,讓客戶端不管該用哪個類的實例,只需要把 '+' 給工廠,工廠自己就給出了相應的實例,客戶端只需要去運算就可以了,不同的實例會實現不同的運算。

但問題也就在這裏:如果要增加一個‘求M的N次方’的功能,就需要給工廠類的‘case’分支加條件,修改了原有的類,這就等於說我們不僅對擴展開放了,對修改也開放了,這就違背了開放-封閉原則。

既然這個工廠類與分支耦合,要消除這種耦合,根據依賴倒轉原則,我們把工廠類抽象出一個接口,這個接口只有一個方法,就是創建抽象產品的工廠方法。然後,所有的要生產具體類的工廠,就去實現這個接口,這樣,一個簡單工廠模式的工廠類,變成了一個工廠抽象接口和多個具體的生成對象的工廠,於是我們要增加‘求M的N次方’的功能時,就不需要更改原有工廠類了,只需要增加此功能的運算類和相應的工廠就可以了。 這樣整個工廠和產品體系其實都沒有修改的變化,而只是擴展的變化,這就完全符合了開放-封閉原則的精神。

工廠方法模式實現時,客戶端需要決定實例化哪一個工廠來實現運算類,選擇判斷的問題還是存在的,也就是說,工廠方法把簡單工廠的內部邏輯判斷移到了客戶端代碼進行。你想要加功能,本來是改工廠類的,而現在是修改客戶端!

工廠方法模式實現:

(其中用到了簡單工廠模式中的類)

工廠接口

public interface IFactory {
    Operation createOperation();
}

加法工廠

public class AddFactory implements IFactory {
    @Override
    public Operation createOperation() {
        // 返回加法操作類實例
        return new OperationAdd();
    }
}

減法工廠

public class SubFactory implements IFactory {
    @Override
    public Operation createOperation() {
        // 返回減法操作類實例
        return new OperationSub();
    }
}

乘法工廠

public class MulFactory implements IFactory {
    @Override
    public Operation createOperation() {
        // 返回乘法操作類實例
        return new OperationMul();
    }
}

除法工廠

public class DivFactory implements IFactory {
    @Override
    public Operation createOperation() {
        // 返回除法操作類實例
        return new OperationDiv();
    }
}

客戶端代碼測試類:

public class FactoryTest {
    public static void main(String[] args) throws Exception {
        IFactory factory = new AddFactory();
        Operation operation = factory.createOperation();
        operation.setNumberA(10);
        operation.setNumberB(20);
        double result = operation.getResult();
        System.out.println(result);
    }
}

OutPut:30.0

總結:

工廠方法克服了簡單工廠違背開放-封閉原則的缺點,又保持了封裝對象創建過程的優點,他們都是集中封裝了對象的創建,使得要更換對象時,不需要做大的改動就能實現,降低了客戶程序與產品對象的耦合。過程方法就是簡單工廠模式的進一步抽象和推廣。但缺點是由於每加一個產品,就需要加一個產品的工廠類,增加了額外的開發量。利用反射可以解決避免分支判斷的問題。這個後面再說。

代碼下載地址:https://gitee.com/nisen6477/design-patterns.git

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