创建型-抽象工厂(Abstract Factory)

抽象工厂(Abstract Factory)

[TOC]

​ 对于抽象工厂的白话定义设计模式之禅中作者给出了一个很好的定义,这里就不班门弄斧了,贴过来,大家仔细看仔细品味~

不知道大家有没有去过工厂,每个工厂分很多车间,每个车间又分多条生产线,分别生产不同的产品,我们可以把八卦炉比喻为车间,把八卦炉生产的工艺(生产白人、黑人还是黄人)称为生产线,如此来看就是一个女性生产车间,专门生产各种肤色的女性,一个是男性生产车间,专门生产各种肤色男性,生产完毕就可以在系统外组装,什么是组装?嘿嘿,自己思考!在这样的设计下,各个车间和各条生产线的职责非常明确,在车间内各个生产出来的产品可以有耦合关系,你要知道世界上黑、黄、白人种的比例是:1∶4∶6,那这就需要女娲娘娘在烧制的时候就要做好比例分配,在一个车间内协调好。这就是抽象工厂模式

定义

Provide an interface for creating families of related or dependent objects without specifyingtheir concrete classes.(为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类。

抽象工厂模式是工厂方法模式的升级版本,在有多个业务品种、业务分类时,通过抽象工厂模式产生需要的对象是一种非常好的解决方式。

结合通用的工厂写法,抽象相当于是在原有的基础上定义的抽象制定的规则,怎么解释呢。。。就是说要new多少种类的对象,那么就应该对应多少个抽象工厂,而相同种类的对象的数量,则是对应抽象工厂中的抽象方法的数量
还是codeing解释比较实在

简单场景

先介绍一下背景,相信大家都或多或少的穿过莆田鞋,或是听说过这个大名鼎鼎的莆田鞋,莆田作为一个历史悠久的制鞋基地,会生产很多很多的鞋,那么这些鞋子根据用途又会有很多分类,这里就只列举两类,运动鞋和皮鞋,而不论什么鞋,都有正品一说,正品好就是正规厂商出品,还有一种就是仿货,所谓的假鞋嘛。

coding

那么两种鞋就对应着两种抽象工厂,而假鞋和正品鞋真是我们工厂里面的抽象方法

/**
     * 运动鞋
     */
    private abstract static class AbsSportsShoes {

    private String name;

    public AbsSportsShoes(String name) {
        this.name = name;
    }

    public void run() {
        System.out.println(name + " sport shoes is running fast");
    }

    public abstract void materail();
}

/**
 * 皮鞋
 */
private abstract static class AbsLeatherShoes {

    private String name;

    public AbsLeatherShoes(String name) {
        this.name = name;
    }

    public void walk() {
        System.out.println(name + " leather shoes is walking slowly");
    }

    public abstract void getColor();
}

private abstract static class AbsAShoesFactory {
    public abstract AbsSportsShoes createASportsShoes();

    public abstract AbsLeatherShoes createALeatherShoes();
}

private abstract static class AbsRealShoesFactory {
    public abstract AbsSportsShoes createRealSportsShoes();

    public abstract AbsLeatherShoes createRealLeatherShoes();
}

上面四个类就对应着咱们的鞋类抽象产品类和对应的抽象产品,他们的划分则是根据写的品种和档次来进行拆分的

private static class ASportsShoes extends AbsSportsShoes {

    public ASportsShoes(String name) {
        super(name);
    }

    @Override
    public void materail() {
        System.out.println("i use jia cai liao");
    }
}

private static class RealSportsShoes extends AbsSportsShoes {

    public RealSportsShoes(String name) {
        super(name);
    }

    @Override
    public void materail() {
        System.out.println("i use real cai liao");
    }
}

private static class ALeatherShoes extends AbsLeatherShoes {

    public ALeatherShoes(String name) {
        super(name);
    }

    @Override
    public void getColor() {
        System.out.println("i am black");
    }
}

private static class RealLeatherShoes extends AbsLeatherShoes {

    public RealLeatherShoes(String name) {
        super(name);
    }

    @Override
    public void getColor() {
        System.out.println("i am white");
    }
}

/**
     * 正品鞋工厂
     */
private static class RealShoesFactory extends AbsRealShoesFactory {

    @Override
    public AbsSportsShoes createRealSportsShoes() {
        return new RealSportsShoes("real sport shoes");
    }

    @Override
    public AbsLeatherShoes createRealLeatherShoes() {
        return new RealLeatherShoes("real leather shoes");
    }
}

/**
 * 假鞋工厂
 */
private static class AShoesFactory extends AbsAShoesFactory {

    @Override
    public AbsSportsShoes createASportsShoes() {
        return new ASportsShoes("adidasi");
    }

    @Override
    public AbsLeatherShoes createALeatherShoes() {
        return new ALeatherShoes("belee");
    }
}

上面的代码就是正品运动鞋和正品皮鞋的实现类以及假鞋的实现类,加上实际工厂的实现类。类数量很多,但是条理清晰,接下来我们是我们的run+console

public static void main(String[] args) {

    AShoesFactory aShoesFactory = new AShoesFactory();
    AbsSportsShoes aSportsShoes = aShoesFactory.createASportsShoes();
    aSportsShoes.materail();
    aSportsShoes.run();
    AbsLeatherShoes aLeatherSHoes = aShoesFactory.createALeatherShoes();
    aLeatherSHoes.getColor();
    aLeatherSHoes.walk();

    RealShoesFactory realShoesFactory = new RealShoesFactory();
    AbsSportsShoes realSportsShoes = realShoesFactory.createRealSportsShoes();
    realSportsShoes.materail();
    realSportsShoes.run();
    AbsLeatherShoes realLeatherShoes = realShoesFactory.createRealLeatherShoes();
    realLeatherShoes.getColor();
    realLeatherShoes.walk();
}

//log
//i use jia cai liao
//adidasi sport shoes is running fast
//i am black
//belee leather shoes is walking slowly
//i use real cai liao
//real sport shoes sport shoes is running fast
//i am white
//real leather shoes leather shoes is walking slowly

条理清晰的上层调用代码,上层并不关系实现类的实现,只负责持有接口和调用。没有任何一个方法与实现类有关系,对于一个产品来说,我们只要知道它的工厂方法就可以直接产生一个产品对象,无须关心它的实现类

抽象工厂的优点:

  • 封装性,高层模块只需要持有功能模块的抽象接口,完全不需要关心功能模块的具体实现,由工厂来负责创建抽象的实现类对象,实现上下层的解耦
  • 产品(对象)之间的约束不对上层公开,上层纯关心应用之间的业务,而工厂作为维护下层产品间的约束关系的中间件

抽象工厂的缺点:

  • 产品族扩展困难,抽象工厂的抽象方法数量由产品族的数量决定,这样在进行扩展的时候原本的工厂实现类就必须统统实现一遍新增加的接口
    抽象类和接口是一个契约。改变契约,所有与契约有关系的代码都要修改

使用场景

惯例贴上:

​ 一个对象族(或是一组没有任何关系的对象)都有相同的约束,则可以使用抽象工厂模式。那么什么是对象族?其实就是同一类别下具有各自实现的产品,笼统举个例子就好比家禽,鸡,鸭,鹅之类就是在家禽族中的成员,他们是同级的,而他们的外貌啊,肉质这些则不一样,有着各自的实现,无论什么实现,肉都是用来吃,外貌用来辨别,此等意义是一样的。

注意事项

这里就直接搬过来了,很通俗易懂

在抽象工厂模式的缺点中,我们提到抽象工厂模式的产品族扩展比较困难 ,但是一定要清楚,是产品族扩展困难,而不是产品等级。在该模式下,产品等级是非常容易扩展的,增加一个产品等级,只要增加一个工厂类负责新增加出来的产品生产任务即可。也就是说横向扩展容易,纵向扩展困难。

你可能感兴趣的:(创建型-抽象工厂(Abstract Factory))