3-抽象工厂模式

抽象工厂模式

详细参考:抽象工厂模式 | 菜鸟教程 (runoob.com)

工厂模式对比

  • 工厂方法模式

    • 每个具体工厂只有一个或者一组重载的工厂方法,只能生产一种产品,可能会导致系统中存在大量的工厂类,势必会增加系统的开销
  • 抽象工厂模式

    • 一个工厂可以生产一系列产品(一族产品),极大减少了工厂类的数量

产品等级结构与产品族

  • 产品等级结构:产品等级结构即产品的继承结构(通俗来说就是产品的种类数量

  • 产品族:产品族是指由同一个工厂生产的位于不同产品等级结构中的一组产品

image-20221121201310034

模式动机
  • 当系统所提供的工厂生产的具体产品并不是一个简单的对象,而是多个位于不同产品等级结构、属于不同类型的具体产品时就可以使用抽象工厂模式

  • 抽象工厂模式是所有形式的工厂模式中最为抽象和最具一般性的一种形式

image-20221121201555609

抽象工厂模式的定义

image-20221121201635800

属于对象创建型模式

抽象工厂模式的应用例子:

  1. 软件的皮肤

    • 每一套皮肤会拥有不同的按钮,窗口,提示窗等
  1. 又称为工具(Kit)模式

  2. 抽象工厂模式中的具体工厂不只是创建一种产品,它负责创建一族产品

  3. 当一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象时,抽象工厂模式比工厂方法模式更为简单、更有效率

抽象工厂模式结构

image-20221121202058939

产品等级结构:A、B

产品族:两个(两个具体工厂)

抽象工厂模式:

  1. 如果只增加新的产品族(即增加一个新的具体工厂或同时在原有产品等级结构上进行扩展)则符合开闭原则,不用修改源代码。

  2. 如果需要增加新的产品等级结构C则需要修改源代码(Factory接口需要增加相关代码),因此不符合开闭原则

综上而言:对于抽象工厂模式来说,增加新的产品族是方便的。

抽象工厂模式包含以下角色:
  • AbstractFactory(抽象工厂)

  • ConcreteFactory(具体工厂)

  • AbstractProduct(抽象产品)

  • ConcreteProduct(具体产品)

典型的抽象工厂类代码
1
2
3
4
5
public interface AbstractFactory {
public AbstractProductA createProductA(); //工厂方法一
public AbstractProductB createProductB(); //工厂方法二
……
}
典型的具体工厂类代码
1
2
3
4
5
6
7
8
9
10
11
12
public class ConcreteFactory1 implements AbstractFactory {
//工厂方法一
public AbstractProductA createProductA() {
return new ConcreteProductA1();
}

//工厂方法二
public AbstractProductB createProductB() {
return new ConcreteProductB1();
}
……
}
实例类图1:
image-20221121203218866 image-20221121203227879

(1) Button:按钮接口,充当抽象产品

(2) SpringButton:Spring按钮类,充当具体产品

(3) SummerButton:Summer按钮类,充当具体产品

(4) TextField:文本框接口,充当抽象产品

(5) SpringTextField:Spring文本框类,充当具体产品

(6) SummerTextField:Summer文本框类,充当具体产品

(7) ComboBox:组合框接口,充当抽象产品

(8) SpringComboBox:Spring组合框类,充当具体产品

(9) SummerComboBox:Summer组合框类,充当具体产品

(10) SkinFactory:界面皮肤工厂接口,充当抽象工厂

(11) SpringSkinFactory:Spring皮肤工厂,充当具体工厂

(12) SummerSkinFactory:Summer皮肤工厂,充当具体工厂

(13) Client:客户端测试类

配置文件

修改类名即可切换产品族

1
2
3
4
5
6
<?xml version="1.0"?>
<config>
<className>
designpatterns.abstractfactory.SpringSkinFactory
</className>
</config>

其它和工厂方法模式相似

进一步地可以将xml文件的修改做成可视化界面

开闭原则的倾斜性

  1. 增加产品族符合开闭原则;

  2. 增加产品等级结构不符合开闭原则。

模式优点

  1. 隔离了具体类的生成,使得客户端并不需要知道什么被创建

  2. 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象

  3. 增加新的产品族很方便,无须修改已有系统,符合开闭原则

模式缺点

  1. 增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大的不便,违背了开闭原则

模式适用环境

  1. 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节(不用知道创建的具体细节)

  2. 系统中有多于一个的产品族,但每次只使用其中某一产品族

  3. 属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来(严格按照一个具体工厂提供一个产品族)

  4. 产品等级结构稳定,在设计完成之后不会向系统中增加新的产品等级结构或者删除已有的产品等级结构(不经常增加产品等级结构

三种工厂模式对比的三个角度

从结构(类图):
  1. 简单工厂模式:一个继承结构(一种抽象产品)

  2. 工厂方法模式:两个继承结构(一个抽象工厂、一种抽象产品)

  3. 抽象工厂模式:继承结构大于等于3个(一个抽象工厂、两个或多个抽象产品)

演化关系:

抽象工厂模式(一个产品等级结构,即只有一个抽象产品类时)退化\stackrel{退化}{\longrightarrow}工厂方法模式(只有一个工厂时)退化\stackrel{退化}{\longrightarrow}简单工厂模式

开闭原则:
  1. 简单工厂模式:违背开闭原则

  2. 工厂方法模式:符合开闭原则

  3. 抽象工厂模式:对增加产品族符合,对增加产品等级结构不符合(开闭原则的倾斜性

  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2023-2024 Guijie Wang
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信