悟空模式-java-抽象工廠模式

【一朝,王母娘娘設宴,大開寶閣,瑤池中作蟠桃勝會】html

有一天,王母娘娘要在瑤池辦party,就須要準備大量的食材。要知道,天上的神仙也分三六九等,九曜星、五方將、二十八宿、四大天王、十二元辰、五方五老、普天星相、河漢羣神等等,不一樣等級的神仙在宴會中吃的東西也不同。java

爲了方便管理,咱們把神仙分爲低級神仙、中級神仙和高級神仙,不一樣等級的神仙將領取到對應等級的食物,因此就有了低級神仙食物、中級神仙食物和高級神仙食物。設計模式

在前面的悟空模式-java-普通工廠模式悟空模式-java-工廠方法模式中都介紹了低級蟠桃(三千年)、中級蟠桃(六千年)和高級蟠桃(九千年),雖然是蟠桃盛會,但也總不能光吃蟠桃,因此由兜率宮拿出了一批仙丹,分爲低級仙丹(煉三三得九天)、中級仙丹(煉七七四十九天)和高級仙丹(煉九九八十一天)。ide

以上,就是咱們本次演示抽象工廠模式所須要的產品元素。學習

在前面咱們說過,當產品愈來愈多,會使得工廠愈來愈難管理,要麼工廠的數量愈來愈多,要麼工廠自己愈來愈複雜,因此,這裏介紹了抽象工廠模式,用於產生較爲複雜的產品結構下的工廠,它與工廠方法最基本的區別是抽象工廠模式可以建立不一樣種類的產品,也就可以更加方便地基於抽象的概念管理一大堆複雜的產品對象。spa

首先咱們介紹兩個概念:產品族與產品等級。設計

所謂產品族,就是由功能相關聯的不一樣種類產品組成的家族,好比咱們最終所須要的低級神仙食物,它是由低級蟠桃與低級仙丹組成的。而產品等級就是對於某一種類的產品,內部劃分的等級結構,如蟠桃內部被劃分爲低級、中級與高級,產品等級是面向同一種類的產品的內部區別描述。code

在一開始,咱們須要建立一個抽象工廠,這個抽象工廠中描述了每一個具體工廠須要提供哪些實現。而後針對每個產品族建立一個工廠,用於統一建立不一樣類型的產品。類圖以下:htm

從圖中能夠看到,不一樣等級的產品交給了不一樣的工廠去建立,用戶只須要調用本身的目標產品族對應的工廠,獲取最終的產品族便可,至於這個產品系列內部結構如何變化,用戶並不須要關心。接下來是具體的實現:對象

蟠桃

package com.tirion.design.abstraction.factory;

public interface FlatPeach {

    void printLevel();

    void printCycleTime();
}

低級蟠桃

package com.tirion.design.abstraction.factory;

public class LowLevelFlatPeach implements FlatPeach {

    LowLevelFlatPeach(){
        printCycleTime();
        printLevel();
    }

    @Override
    public void printLevel() {
        System.out.println("低級蟠桃");
    }

    @Override
    public void printCycleTime() {
        System.out.println("三千年一熟");
    }

}

中級蟠桃

package com.tirion.design.abstraction.factory;

public class MiddleLevelFlatPeach implements FlatPeach {

    MiddleLevelFlatPeach(){
        printCycleTime();
        printLevel();
    }

    @Override
    public void printLevel() {
        System.out.println("中級蟠桃");
    }

    @Override
    public void printCycleTime() {
        System.out.println("六千年一熟");
    }

}

高級蟠桃

package com.tirion.design.abstraction.factory;

public class HighLevelFlatPeach implements FlatPeach {

    HighLevelFlatPeach(){
        printCycleTime();
        printLevel();
    }

    @Override
    public void printLevel() {
        System.out.println("高級蟠桃");
    }

    @Override
    public void printCycleTime() {
        System.out.println("九千年一熟");
    }

}

仙丹

package com.tirion.design.abstraction.factory;

public interface Elixir {

    void printLevel();

    void printCycleTime();
}

低級仙丹

package com.tirion.design.abstraction.factory;

public class LowLevelElixir implements Elixir {

    LowLevelElixir(){
        printCycleTime();
        printLevel();
    }

    @Override
    public void printLevel() {
        System.out.println("低級仙丹");
    }

    @Override
    public void printCycleTime() {
        System.out.println("煉三三得九天");
    }

}

中級仙丹

package com.tirion.design.abstraction.factory;

public class MiddleLevelElixir implements Elixir {

    MiddleLevelElixir(){
        printCycleTime();
        printLevel();
    }

    @Override
    public void printLevel() {
        System.out.println("中級仙丹");
    }

    @Override
    public void printCycleTime() {
        System.out.println("煉七七四十九天");
    }

}

高級仙丹

package com.tirion.design.abstraction.factory;

public class HighLevelElixir implements Elixir {

    HighLevelElixir(){
        printCycleTime();
        printLevel();
    }

    @Override
    public void printLevel() {
        System.out.println("高級仙丹");
    }

    @Override
    public void printCycleTime() {
        System.out.println("煉九九八十一天");
    }

}

抽象工廠-神仙食物工廠

package com.tirion.design.abstraction.factory;

public interface XianFoodFactory {

    FlatPeach prepareFlatPeach();

    Elixir prepareElixir();

}

低級神仙食物工廠

package com.tirion.design.abstraction.factory;

public class LowLevelXianFoodFactory implements XianFoodFactory {

    @Override
    public FlatPeach prepareFlatPeach() {
        return new LowLevelFlatPeach();
    }

    @Override
    public Elixir prepareElixir() {
        return new LowLevelElixir();
    }


}

中級神仙食物工廠

package com.tirion.design.abstraction.factory;

public class MiddleLevelXianFoodFactory implements XianFoodFactory {

    @Override
    public FlatPeach prepareFlatPeach() {
        return new MiddleLevelFlatPeach();
    }

    @Override
    public Elixir prepareElixir() {
        return new MiddleLevelElixir();
    }


}

高級神仙食物工廠

package com.tirion.design.abstraction.factory;

public class HighLevelXianFoodFactory implements XianFoodFactory {

    @Override
    public FlatPeach prepareFlatPeach() {
        return new HighLevelFlatPeach();
    }

    @Override
    public Elixir prepareElixir() {
        return new HighLevelElixir();
    }


}

王母娘娘-調用者

package com.tirion.design.abstraction.factory;


public class TheQueenMother {

    public static void prepareXianFood(XianFoodFactory xianFoodFactory) {
        xianFoodFactory.prepareFlatPeach();
        xianFoodFactory.prepareElixir();
    }

    public static void main(String[] args) {
        System.out.println("準備低級神仙食物...");
        TheQueenMother.prepareXianFood(new LowLevelXianFoodFactory());
        System.out.println("準備中級神仙食物...");
        TheQueenMother.prepareXianFood(new MiddleLevelXianFoodFactory());
        System.out.println("準備高級神仙食物...");
        TheQueenMother.prepareXianFood(new HighLevelXianFoodFactory());
    }
}

代碼執行結果

準備低級神仙食物...
三千年一熟
低級蟠桃
煉三三得九天
低級仙丹
準備中級神仙食物...
六千年一熟
中級蟠桃
煉七七四十九天
中級仙丹
準備高級神仙食物...
九千年一熟
高級蟠桃
煉九九八十一天
高級仙丹

使用了抽象工廠模式以後,在面對複雜的宴會菜單對象時,王母娘娘不須要關心天宮的御廚如何搭配食物,只須要下達命令要求御廚準備不一樣等級的食物套餐就能夠了。

每一個具體工廠只須要建立本身負責的產品,這符合單一職責原則。

具體工廠返回的產品是產品的抽象而不是具體,因此符合依賴致使原則。

關於開閉原則,抽象工廠模式是一個比較典型的例子。

咱們在使用中能夠發現,若是要添加一個新的產品族,好比王母娘娘專享食物套餐,套餐內容是高級蟠桃,而並不須要吃仙丹(王母娘娘吃仙丹已經沒啥用了),那麼咱們只須要增長一個TheQueenMotherFoodFactory,而後在內部添加具體的實現便可,並不須要更改其餘任何類,很完美地符合了開閉原則。

王母娘娘食物工廠

package com.tirion.design.abstraction.factory;

public class TheQueenMotherFoodFactory implements XianFoodFactory {

    @Override
    public FlatPeach prepareFlatPeach() {
        return new HighLevelFlatPeach();
    }

    @Override
    public Elixir prepareElixir() {
        return null;
    }


}

可是若是某一天,鎮元大仙上供了一批人蔘果,王母娘娘一高興,把人蔘果也做爲宴會的一道主菜,那麼就麻煩了:不只僅抽象工廠XianFoodFactory要增長人蔘果的接口,它的全部實現都要增長相應的接口實現,整個體系才能繼續運轉下去。這時候,抽象工廠模式又不符合開閉原則了。

根據以上描述咱們能夠得出,對於抽象工廠模式,增長產品族符合開閉原則,增長產品種類則不符合開閉原則,也就是說抽象工廠模式具有開閉原則的傾斜性。

注意:抽象工廠模式並非比工廠方法模式更加高級的模式,而是爲了適應不一樣的業務變化狀況而作出的不一樣應對,繼而產生的不一樣解決方案而已。

抽象工廠模式的使用情景:

1.系統中存在多個產品族,用戶只關心產品族,也就是隻關心最終結果

2.屬於同一產品族的產品相互之間具備關聯關係,它們是被組合在一塊兒使用的

抽象工廠模式遵循的設計原則:

1.依賴倒置原則(客戶端依賴的是產品抽象而不是具體產品)

2.迪米特法則

3.里氏替換原則

4.接口隔離原則(使用了多個相互隔離的接口,下降了耦合度)

5.單一職責原則(每一個工廠只要負責建立本身對應產品族的產品)

6.開閉原則(具備傾斜性,支持新增產品族,但不支持新增產品類型)

關於抽象工廠模式的介紹就到這裏,你能夠將它記憶爲蟠桃宴會模式

若是你認爲文章中哪裏有錯誤或者不足的地方,歡迎在評論區指出,也但願這篇文章對你學習java設計模式可以有所幫助。轉載請註明,謝謝。

更多設計模式的介紹請到悟空模式-java設計模式中查看。

相關文章
相關標籤/搜索