意图
提供一个接口,这个接口可以创建一系列相关或相互依赖的产品,而无需指定它们具体的类(隐藏类名)。
别名
Kit
动机
举例问题
(多种系列多种产品)窗口系统中有A种窗口组件,每种窗口组件也有B种风格。(AxB个类)
动机
提供一个抽象工厂生产窗口组件(而不是生产风格),从而隐藏具体类。
示例图形

适用性
- 一个系统在同一时刻下能且仅能配置多个系列中的一个系列时。
- 一个系列里的产品联合使用时。
- 想要提供一个产品类库,但只想显示它们的接口而不是实现时。
结构

参与者
- AbstractFactory:定义一个用于创建抽象产品对象的抽象工厂类。(AbstractFactory可以同时作为ConcreteFactory使用。)
- ConcreteFactory:定义一个用于创建某一系列具体产品对象的具体工厂类。
- AbstractProduct:定义一种抽象产品类。
- ConcreteProduct:定义一个将被相应的具体工厂创建的具体产品类。
- Client:仅使用由AbstractFactory和AbstractProduct声明的接口。
协作
- 运行时创建一个ConcreteFactory类实例。想要创建不同系列的产品对象,Client需要创建不同的ConcreteFactory类实例。
- AbstractFactory将产品对象的创建延迟到它的ConcreteFactory子类。
效果
- 分离了具体的类,客户不再关心创建特定系列特定产品需要用哪个类,只需要关心由AbstractFactory和AbstractProduct声明的接口。
- 更改要生产的产品系列变得容易。仅需要将一种ConcreteFactory切换为另一种ConcreteFactory。
- 有利于产品的一致性。一个应用同一时刻能且仅能使用一个系列。
- 难以扩充新种类产品,若要扩充新种类产品:
- 增加新种类产品的AbstractProduct。
- 通过定义继承新AbstractProduct的多个ConcreteProduct子类完成此产品各种系列。
- 修改AbstractFactory及其所有子类接口。(糟糕的设计!需要修改现有代码。)
- 容易扩充新系列产品:
- 增加一个新系列的ConcreteFactory类。
- 在每一个AbstractProduct类中增加一个新系列的ConcreteProduct子类。
实现(注意点)
- 将ConcreteFactory实现为Singleton(单例类)。
- 每种系列都要有一个对应的具体工厂。
- 若想使扩充新种类产品变得容易,在动态类型语言中可以如此做(静态类型语言由于无法使Make操作返回类型不同,而不容易实现或不安全):
- 使AbstractFactory只包含一个Make操作,然后通过参数(如字符串)来告知工厂要创建的产品名字。
- 维护一个索引表,使Make可以通过1中的参数(字符串)找到具体创建产品的代码块,从而实现委托创建过程。
- 若完成以上两步,客户新增加一个产品时需要做的事有:
- 增加新种类产品的AbstractProduct。
- 通过定义继承新AbstractProduct的多个ConcreteProduct子类完成此产品各种系列。
- 更新索引表。