抽象工厂模式概述
- 定义:提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。
- 抽象工厂,顾名思义,就是比工厂模式更抽象的工厂模式。在工厂模式中,一个具体工厂只负责生产一个具体产品。而在抽象工厂模式中,一个具体工厂可以生产一组相关的产品,这些产品称为产品族,产品族中的每一个产品部分属于每一个产品继承等级结构
- 首先我们先了解下什么是产品族和产品等级结构。
- 产品等级结构即产品的继承结构,好比一个抽象类是汽车,其子类包括奔驰,宝马,大众,保时捷…..这样抽象汽车与具体汽车品牌之间构成了一个产品等级结构,抽象汽车类是父类,具体汽车类是子类。
- 产品族,在抽象工厂模式中,产品族是指由同一个工厂生产的,属于不同产品等级结构中的一组产品。如苹果公司生产的电脑,手机,平板,手表……构成一个产品族
那么,有这两个东西又有什么用呢?我们不妨思考下,在生活中,有不少工厂,每个工厂中也生产各种不同的产品。我们又如何定位到某个具体的产品呢?
如上图,共有15个不同的图形(颜色或样式都不一样),每一行对应一个具体工厂所产生的具体产品(构成产品族),我们只需要指明产品所处的产品族和它所属的产品等级结构,就可以定位到对应的产品。如第4行(第4个产品族)的第三个产品等级结构,就可以定位到那个椭圆形
- 与工厂方法模式的区别
工厂方法模式针对的是一个产品等级结构,而抽象工厂模式面对多个产品等级结构,一个工厂等级结构负责多个不同的产品等级结构中的产品对象的创建。而在工厂方法模式中,一个工厂等级结构生产一个产品等级结构。上述图中的产品如果在工厂方法模式中,需要15个具体工厂,而在抽象工厂模式中,只需要5个工厂,大大减少了工厂类的个数
优点与缺点
优点
- 隔离了具体类的生成,使得客户端不需要知道什么被创建
- 可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。
- 当一个产品族的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族的对象
抽象工厂模式增加新的产品族很容易,无需修改已有系统,符合开闭原则
缺点
增加新的产品结构很麻烦,需要对原有系统进行大规模的修改,甚至需要修改抽象层代码,违背了开闭原则
应用场景
当一个系统不依赖于产品类实例如何被创建、组合和表达的细节,用户无需关心对象的创建过程,将对象的创建和适用解耦
- 系统中有多于一个的产品族,但每次只需要使用其中某一个产品族,可以通过配置文件等动态地改变产品族,也很方便的增加新的产品族
- 属于同一个产品族的产品将一起使用
- 产品等级结构稳定,设计完成后,不会向系统增加i新的产品等级结构或者删除已有的产品等级结构
模式的结构与实现
抽象工厂模式的主要角色如下:
AbstractFactory(抽象工厂):声明了一组用于创建一族产品的方法,每个方法对应一个产品
ConcreteFactory(具体工厂):实现在抽象工厂中声明的创建产品的方法,生成具体产品,构成产品族
AbstractProduct(抽象产品):为每种产品声明接口,它声明了产品具有的业务方法
ConcreteProduct(具体产品):定义具体产品的具体生产对象,实现抽象接口中声明的业务方法
应用实例
在每个OS中,都有一个图形构建组成的构件家族,可以通过一个抽象角色给出功能定义,而由具体子类给出不同OS中的具体实现,例如下两个产品结构,分别是Button和Text,同时包含三个产品族,即Unix产品族,Linux产品族,Windows产品族

注意
- 在抽象工厂模式中,增加新的产品族很容易,只需要增加具体产品并对应增加一个新的具体工厂就可以了,对已有代码不需要进行修改,但是增加新的产品等级结构很麻烦,需要修改所有的工厂角色,包括抽象工厂类,在所有的工厂类中都必须要添加新的产品等级结构,违背了开闭原则,这种特性被称为开闭原则的倾斜性
