抽象工厂

意图

提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

动机

适用性

  • 一个系统要独立于它的产品的创建、组合和表示
  • 一个系统要由多个产品系列中的一个来配置时
  • 强调一系列相关的产品对象的设计便于联合使用时
  • 提供一个产品类库,只想显示接口而不是实现时

结构

优点

  • 它分离了具体的类

  • 使得易于交换产品系列

    一个具体工厂类在一个应用中仅出现一次——在它初始化的时候,这使得改变一个应用的具体工厂变得很容易,只需要重新初始化一个具体工厂类对象即可修改。

  • 有利于产品的一致性

    当一个系列中的产品对象被设计成一起工作时,一个应用一次只能使用同一个系列中的对象。AbstractFactory 模式很容易实现这个。

缺点

  • 难以拓展新种类的产品

    因为拓展新种类产品必须要修改 AbstractFactory 接口及其所有子类。

实现

实现 AbstractFactory 模式的一些有用技术:

  1. 将工厂作为单例模式实现

    一个应用中一般每个产品系列只需一个具体工厂类的实例,因此工厂通常最好实现为一个 Singleton。

  2. 创建产品

    AbstractFactory 仅声明一个创建产品的接口,真正创建产品是由 ConcreteProduct 子类实现的。最通常的一个办法是为每一个产品定义一个工厂方法(FactoryMethod模式)。一个具体的工厂将为每个产品重定义该工厂方法以指定产品。这样的实现虽然很简单,但却要求每个产品系列都要有一个新的具体工厂子类,即使这些产品系列的差别很小。

    如果有多个可能的产品系列,具体工厂也可以使用 Prototype 模式来实现。具体工厂使用产品系列中每一个产品的原型实例来初始化,且它通过复制它的原型来创建新的产品。在基于 Prototype 模式的实现中,使得不是每一个新的产品系列都需要一个新的具体工厂类。

  3. 定义可拓展的工厂

    一个更灵活但不太安全的设计是给创建对象的操作增加一个参数,该参数指定了将被创建的对象的种类。

    与 C++ 这样的静态类型语言相比,这一个设计更容易使用在类似于 Smalltalk 这样的动态类型语言中。要在 C++ 中使用这种设计,要么所有的对象都相同的抽象基类,要么产品对象可以被请求它们的客户安全地强制转换正确类型。但存在一个本质的问题:所有的产品对象通过给定的相同的抽象接口返回给客户时,客户并不能区分或对产品对象的 type 进行安全的判定。即使在 C++ 中可以通过强制向下类型转换,但这并不是总是可行或安全的,因为向下类型转换可能会失败。

相关模式

AbstractFactory 类通常用工厂方法(FactoryMethod)实现,但它们也可以用 Prototype 实现。一个具体的工厂通常是一个单例(Singleton) 。

例子

本文结束感谢您的阅读
感谢打赏,继续前行!