发布于 2年前

创建型设计模式:抽象工厂(Abstract Factory)

我们在使用简单工厂或工厂方法,createProduct()是直接返回了已完成的产品。而有些产品由好几个零部件组装而成,各个零部件单独生产,并相关联。这次我们要介绍的是生产自行车的工厂。

自行车工厂

自行车工厂的任务是:

  1. 生产两个品牌系列:凤牌和凰牌的自行车
  2. 生产自行车的各个系列相关零部件:车架(BikeRack),车轮(Wheel)和脚踏板(Pedal),最后组装自行车。

品牌差异

因为凤牌和凰牌自行车的定位不同,它们各自的车架,车轮和脚踏板的材料以及制作工艺是比较大的差异,所以不能统一在一个工厂生产。

很自然,我们会想到在两个工厂:FengBikePartsFactory和HuangBikePartsFactory生产。

组装所用零部件类别相同

虽然两个品牌零部件不同,但它们所用到的零部件类别规格相同,且组装方式也一样。为了规范零部件的规格和流程,我们抽象规范生产零部件的工厂接口,BikePartsFactory:

<pre data-language-edit="Java" spellcheck="false">```java
<span class="hljs">//规范零部件车架</span>
<span class="hljs">public</span> <span class="hljs">abstract</span> <span class="hljs">class</span> <span class="hljs">BikeRack</span> {
}
<span class="hljs">//规范零部件脚踏</span>
<span class="hljs">public</span> <span class="hljs">abstract</span> <span class="hljs">class</span> <span class="hljs">Pedal</span> {
}
<span class="hljs">//规范零部件车轮</span>
<span class="hljs">public</span> <span class="hljs">abstract</span> <span class="hljs">class</span> <span class="hljs">Wheel</span> {
}
<span class="hljs">public</span> <span class="hljs">abstract</span> <span class="hljs">class</span> <span class="hljs">BikePartsFactory</span> {
    <span class="hljs">abstract</span> BikeRack <span class="hljs">createRack()</span>;
    <span class="hljs">abstract</span> Wheel <span class="hljs">createWheel()</span>;
    <span class="hljs">abstract</span> Pedal <span class="hljs">createPedal()</span>;
}

各自工厂就可以继承BikePartsFacotry,生产各自的零部件。

### 凤自行车零部件工厂

凤自行车的零部件实现零部件的接口,最后由FengBikePartsFactory生产。

<pre data-language-edit="Java" spellcheck="false">```java <span class="hljs">//实现BikeRack要求,满足自行车架规格</span> <span class="hljs">public</span> <span class="hljs">class</span> <span class="hljs">FengBikeRack</span> <span class="hljs">extends</span> <span class="hljs">BikeRack</span>{} <span class="hljs">public</span> <span class="hljs">class</span> <span class="hljs">FengWheel</span> <span class="hljs">extends</span> <span class="hljs">Wheel</span> {} <span class="hljs">public</span> <span class="hljs">class</span> <span class="hljs">FengPedal</span> <span class="hljs">extends</span> <span class="hljs">Pedal</span>{}

<span class="hljs">public</span> <span class="hljs">class</span> <span class="hljs">FengBikePartsFactory</span> <span class="hljs">extends</span> <span class="hljs">BikePartsFactory</span>{ <span class="hljs">@Override</span> BikeRack <span class="hljs">createRack()</span> { <span class="hljs">return</span> <span class="hljs">new</span> <span class="hljs">FengBikeRack</span>(); } <span class="hljs">@Override</span> Wheel <span class="hljs">createWheel()</span> { <span class="hljs">return</span> <span class="hljs">new</span> <span class="hljs">FengWheel</span>(); } <span class="hljs">@Override</span> Pedal <span class="hljs">createPedal()</span> { <span class="hljs">return</span> <span class="hljs">new</span> <span class="hljs">FengPedal</span>(); } }

凰自行车零部件工厂

同样,凰自行车零部件实现零部件的接口,最后由HuangBikePartsFactory生产。

<pre data-language-edit="Java" spellcheck="false">```java
<span class="hljs">//实现BikeRack要求,满足自行车架规格</span>
<span class="hljs">public</span> <span class="hljs">class</span> <span class="hljs">HuangBikeRack</span> <span class="hljs">extends</span> <span class="hljs">BikeRack</span>{}
<span class="hljs">public</span> <span class="hljs">class</span> <span class="hljs">HuangWheel</span> <span class="hljs">extends</span> <span class="hljs">Wheel</span> {}
<span class="hljs">public</span> <span class="hljs">class</span> <span class="hljs">HuangPedal</span> <span class="hljs">extends</span> <span class="hljs">Pedal</span>{}

<span class="hljs">public</span> <span class="hljs">class</span> <span class="hljs">HuangBikePartsFactory</span> <span class="hljs">extends</span> <span class="hljs">BikePartsFactory</span>{
    <span class="hljs">@Override</span>
    BikeRack <span class="hljs">createRack()</span> {
        <span class="hljs">return</span> <span class="hljs">new</span> <span class="hljs">HuangBikeRack</span>();
    }
    <span class="hljs">@Override</span>
    Wheel <span class="hljs">createWheel()</span> {
        <span class="hljs">return</span> <span class="hljs">new</span> <span class="hljs">HuangWheel</span>();
    }
    <span class="hljs">@Override</span>
    Pedal <span class="hljs">createPedal()</span> {
        <span class="hljs">return</span> <span class="hljs">new</span> <span class="hljs">HuangPedal</span>();
    }
}

### 自行车组装

简化实现中的自行车组装,组装车间只需要拿到每个品牌各自的一套零部件,就可以按标准流程组装完成。

<pre data-language-edit="Java" spellcheck="false">```java <span class="hljs">public</span> <span class="hljs">class</span> <span class="hljs">BikeAssemble</span> { <span class="hljs">private</span> BikePartsFactory bikePartsFactory;

<span class="hljs">public</span> <span class="hljs">BikeAssemble(BikePartsFactory bikePartsFactory)</span> {
    <span class="hljs">this</span>.bikePartsFactory = bikePartsFactory;
}

<span class="hljs">public</span> Bike <span class="hljs">create()</span> {
    <span class="hljs">BikeRack</span> <span class="hljs">bikeRack</span> <span class="hljs">=</span> bikePartsFactory.createRack();
    <span class="hljs">Wheel</span> <span class="hljs">wheel</span> <span class="hljs">=</span> bikePartsFactory.createWheel();
    <span class="hljs">Pedal</span> <span class="hljs">pedal</span> <span class="hljs">=</span> bikePartsFactory.createPedal();
    <span class="hljs">return</span> <span class="hljs">new</span> <span class="hljs">Bike</span>(bikeRack,wheel, pedal);
}

}

那么要生产凤自行车和凰自行车,只要告诉那个零部件工厂生产即可。

生产方式:

<pre data-language-edit="Java" spellcheck="false">```java
<span class="hljs">public</span> <span class="hljs">static</span> <span class="hljs">void</span> <span class="hljs">main(String[] args)</span> {
        <span class="hljs">//生产凤自行车</span>
        <span class="hljs">BikeAssemble</span> <span class="hljs">assemble</span> <span class="hljs">=</span> <span class="hljs">new</span> <span class="hljs">BikeAssemble</span>(<span class="hljs">new</span> <span class="hljs">FengBikePartsFacotry</span>());
        <span class="hljs">Bike</span> <span class="hljs">fengBike</span> <span class="hljs">=</span> assemble.create();

        <span class="hljs">//生产凰自行车</span>
        <span class="hljs">BikeAssemble</span> <span class="hljs">assemble</span> <span class="hljs">=</span> <span class="hljs">new</span> <span class="hljs">BikeAssemble</span>(<span class="hljs">new</span> <span class="hljs">HuangBikePartsFacotry</span>());
        <span class="hljs">Bike</span> <span class="hljs">huangBike</span> <span class="hljs">=</span> assemble.create();
 }


抽象工厂
----

上述生产自行车的工厂使用就是我们要介绍的设计模式:**抽象工厂**。

> **抽象工厂模式:**提供一个接口,用于创建相关或者依赖对象的系列,而不需要明确指定具体类。

抽象工厂是创建型设计模式,类图如下:

<figure class="image">![](https://uimg.majing.io/post/1/36/3507/1664010489521_GX6Bd.png)</figure>AbstractFactory:抽象工厂会提供接口生成相关或者相互依赖的产品家族。

ConcreteFactory:具体化工厂,它会实现抽象工厂提供的生成产品家族接口。

ProductA:相关联家族的产品抽象,由抽象定义创建产品方法。

ConcreteProduct:具体的产品,实现抽象产品接口ProductA,并在系列的具体工厂实现创建。

Client:调用工厂,组合具体工厂创建的相关产品,创建最终产品。

抽象工厂 VS 工厂方法
------------

1. 工厂方法只提供用一个方法,而抽象工厂提供产品家族的多个创建方法。
2. 工厂方法往往创建的是单一产品,而抽象工厂创建的是相关或者相互依赖的产品家族。

相关文章

©2020 edoou.com   京ICP备16001874号-3