悟空模式-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设计模式中查看。

相关文章
相关标签/搜索