工厂模式之抽象工厂模式

288 阅读7分钟

工厂模式之抽象工厂模式

图片

夏天到了,我开着宝马,但是却看不到我女朋友开心的笑容了?

图片

我:宝贝,你这是怎么了?怎么不开心了。

图片

女朋友:你看这大热天的,咱们这个车蒙的慌,虽然你单手开着宝马是很酷,但是我已经热的没心情看你开车了。

图片

我很爱我的女朋友,为了让我的女朋友能够再次开心起来,我就去找宝马公司,让他们给我车安装个空调。

一、工厂模式之抽象工厂模式

1.1 前言

随着客户的要求越来越高,宝马车需要配置空调。于是这个工厂开始生产宝马车和配置需要的空调。

这时候工厂有二个系列的产品:宝马车和空调。

宝马车必须使用对应的空调才能使用。这时候如果分别使用一个车工厂和一个空调工厂都不能满足我们的需求,我们必须确认车跟空调的对应关系。因此把车工厂跟空调工厂联系在一起。因此出现了抽象工厂模式。

可以说,抽象工厂模式和工厂方法模式的区别就在于需要创建对象的复杂程度上。而且抽象工厂模式是三个里面最为抽象、最具一般性的。

1.2 抽象工厂模式组成

抽象工厂模式的各个角色(和工厂方法基本一样):

  1. 抽象工厂角色:这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。

  2. 具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。

  3. 抽象产品族角色:它是具体产品继承的父类或者是实现的接口。

  4. 具体产品角色:具体工厂角色所创建的对象就是此角色的实例。

1.3 抽象工厂模式类图

宝马公司根据新的构想,重新让设计师重构了设计图:

图片

1.4 抽象工厂模式实现

有了设计图之后,宝马公司重新对他们的公司进行了配置,主要是对公司进行了重新规范,工厂不仅仅要生产车,还需要生产对应型号的空调。

1.4.1 抽象产品角色BMW

抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。

BMW和工厂方法模式的一样,这里直接贴代码(具体为什么这么设计请看工厂方法模式篇章):

抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。

BMW和工厂方法模式的一样,这里直接贴代码(具体为什么这么设计请看工厂方法模式篇章):

package com.kfit.factory.bmw.abstractfactory;

/\*\*
 \* BMW 的超类
 \*
 \* @author 悟纤「公众号SpringBoot」
 \* @date 2020-11-19
 \* @slogan 大道至简 悟在天成
 \*/
public abstract class BMW {
    public  BMW(){
        System.out.println("BMW制造 - 统一的部分...");
    }

    /\*\*
     \* 定义抽象方法:所有的宝马车都要能进行运行。
     \* 具体怎么运行,在抽象类中就不管了
     \*
     \*/
    public abstract void run();

}

这里我们还有另外一个空调的产品,我们也需要定义定义一下Aircondition:

package com.kfit.factory.bmw.abstractfactory;

/\*\*
 \* 空调抽象类
 \*
 \* @author 悟纤「公众号SpringBoot」
 \* @date 2020-11-19
 \* @slogan 大道至简 悟在天成
 \*/
public abstract class Aircondition {

    //相应的抽象方法,这里并未定义.

}

1.4.2 具体产品角色BMW520/BMW521

具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。

BMW520/BMW521和工厂方法模式的一样,这里直接贴代码(具体为什么这么设计请看工厂方法模式篇章):

BMW520**:**

package com.kfit.factory.bmw.abstractfactory;

/\*\*
 \* BMW520
 \*
 \* @author 悟纤「公众号SpringBoot」
 \* @date 2020-11-19
 \* @slogan 大道至简 悟在天成
 \*/
public class BMW520 extends BMW {

    public BMW520(){
        System.out.println("制造宝马520系列");
    }

    /\*\*
     \*  运行
     \*/
    @Override
    public void run(){
        System.out.println("单手开着宝马520,载着女朋友...");
    }

}

BMW521**:**

package com.kfit.factory.bmw.abstractfactory;

/\*\*
 \* BMW520
 \*
 \* @author 悟纤「公众号SpringBoot」
 \* @date 2020-11-19
 \* @slogan 大道至简 悟在天成
 \*/
public class BMW521 extends BMW {

    public BMW521(){
        System.out.println("制造宝马521系列");
    }

    /\*\*
     \*  运行
     \*/
    @Override
    public void run(){
        System.out.println("单手开着宝马521,载着女朋友...");
    }

}

对应空调产品的实现:Aircondition520/Airconodition521:

Aircondition520:

package com.kfit.factory.bmw.abstractfactory;

/\*\*
 \* 520型号的空调
 \*
 \* @author 悟纤「公众号SpringBoot」
 \* @date 2020-11-19
 \* @slogan 大道至简 悟在天成
 \*/
public class Aircondition520 extends Aircondition {

}

Aircondition521:

package com.kfit.factory.bmw.abstractfactory;

/\*\*
 \* 521型号的空调
 \*
 \* @author 悟纤「公众号SpringBoot」
 \* @date 2020-11-19
 \* @slogan 大道至简 悟在天成
 \*/
public class Aircondition521 extends Aircondition {

}

1.4.3 抽象工厂角色BMWFactory

抽象工厂角色:这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。

宝马公司给所有的公司指定了一套标准,每个工厂都需要有一个生产车(createBMW)和空调(createAirc)的能力,怎么你们车和空调的生产过程,对于总部就不过多干涉了。

BMWFactory可以是抽象类,也可以是接口,接口是可以满足的情况,优先接口,面向接口编程:

package com.kfit.factory.bmw.abstractfactory;

/\*\*
 \* 宝马工厂
 \*
 \* @author 悟纤「公众号SpringBoot」
 \* @date 2020-11-19
 \* @slogan 大道至简 悟在天成
 \*/
public interface BMWFactory {

    /\*\*
     \* 专门生产宝马的方法
     \* @return
     \*/
    BMW createBMW();

    /\*\*
     \* 定义生成空调的方法
     \* @return
     \*/
    Aircondition createAirc();
}

1.4.3 具体工厂角色BMWFactory520/BMWFactory521

具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。

对于宝马520和宝马521这两个系列,为了管理的方便(程序就是扩展能力),在北京开办了一个专门生产宝马520和配套520的空调,在上海开办了专门生产宝马521和配套521的空调。

BMWFactory520:

package com.kfit.factory.bmw.abstractfactory;

/\*\*
 \* 宝马520的工厂
 \*
 \* @author 悟纤「公众号SpringBoot」
 \* @date 2020-11-19
 \* @slogan 大道至简 悟在天成
 \*/
public class BMWFactory520 implements BMWFactory {

    @Override
    public BMW createBMW() {
        return new BMW520();
    }

    @Override
    public Aircondition createAirc() {
        return new Aircondition520();
    }
}

BMWFactory521:

package com.kfit.factory.bmw.abstractfactory;

/\*\*
 \* BMW 521的工厂
 \*
 \* @author 悟纤「公众号SpringBoot」
 \* @date 2020-11-19
 \* @slogan 大道至简 悟在天成
 \*/
public class BMWFactory521 implements BMWFactory {
    @Override
    public BMW createBMW() {
        return new BMW521();
    }

    @Override
    public Aircondition createAirc() {
        return new Aircondition521();
    }
}

**1.5 Me-**买车来了

宝马公司:我们的SVIP客户,我们新款的车已经支持空调了,优惠给您。

我:好的,立马到。

为了给我女朋友一个惊喜,我没有告诉我的女朋友,我就过去把车提了:

package com.kfit.factory.bmw.abstractfactory;
/\*\*
 \* 我 - Customer
 \*
 \* @author 悟纤「公众号SpringBoot」
 \* @date 2020-11-19
 \* @slogan 大道至简 悟在天成
 \*/
public class Me {
    public static void main(String\[\] args) {
        /\*\*
         \* 我和我女朋友度假回来了,要来看看车:
         \*/
        // 来 宝马公司 给我来个520看看
        BMWFactory factory = new BMWFactory520();
        BMW bmw = factory.createBMW();
        Aircondition aircondition = factory.createAirc();
        //车来了,我带着我的女朋友去溜达一下
        bmw.run();
        //aircondition.run() 运行空调

        // 来 宝马公司 给我来个521看看
        factory = new BMWFactory521();
        bmw = factory.createBMW();
        aircondition = factory.createAirc();
        //车来了,我带着我的女朋友去溜达一下
        bmw.run();
        //aircondition.run() 运行空调
    }
}

当我把拥有空调的车开到我女朋友面前的时候,我女朋友开心的合不拢嘴,给我来了一个大大大地拥抱。我也是很开心很开心。亲爱的,爱你一万年。

空调车在手,夏天不热,冬天不冷,带着女朋友说走就走。