-
描述
抽象工厂模式(Abstract factory pattern)提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
在使用中,用户利用抽象工厂来创建一系列相关的具体产品,并仅使用抽象产品的通用接口来操纵创建的具体产品,而不需要知道创建的具体产品类型。抽象工厂模式的目的是将若干抽象产品的接口与不同主题产品的具体实现分离开。这样就能在增加新的具体工厂的时候,不用修改引用抽象工厂的客户端代码。
BUILDER模式侧重于产品构建过程的封装,而抽象工厂侧重于一系列相关产品构建过程的封装。
-
实现
抽象工厂接口,包含一系列相关产品的创建接口:
interface AbstractFactory { ProductA createProductA(); ProductB createProductB(); }
抽象产品接口,包含产品的通用接口:
interface ProductA {} interface ProductB {}
具体的产品实现类:
public class ProductA1 implements ProductA {} public class ProductB1 implements ProductB {} public class ProductA2 implements ProductA {} public class ProductB2 implements ProductB {}
具体工厂子类,覆盖实现创建具体产品:
public class ConcreteFactory1 implements AbstractFactory { public ProductA createProductA() { return new ProductA1(); } public ProductB createProductB() { return new ProductB1(); } } public class ConcreteFactory2 implements AbstractFactory { public ProductA createProductA() { return new ProductA2(); } public ProductB createProductB() { return new ProductB2(); } }
客户端程序
public class UserClass { public static void main(String[] args){ // 客户要产品系列1 AbstractFactory factory1 = new ConcreteFactory1(); ProductA productA1 = factory1.createProductA(); ProductB productB1 = factory1.createProductB(); // 客户要产品系列2 AbstractFactory factory2 = new ConcreteFactory2(); ProductA productA2 = factory1.createProductA(); ProductB productB2 = factory1.createProductB(); } }
实现的一些常用方法:
- 将工厂实现为单例:一个应用中一般每个产品系列只需一个ConcreteFactory的实例。因此工厂通常最好实现为Singleton的方式。
- AbstractFactory仅声明一个创建产品的接口,真正创建产品是由ConcreteFactory子类实现的。最通常的一个办法是为每一个产品定义一个工厂方法。一个具体的工厂将为每个产品重定义该工厂方法以指定产品。
- 定义可扩展的工厂:AbstractFactory通常为每一种它可以生产的产品定义一个操作。一个更灵活但不太安全的设计是给创建对象的操作增加一个参数。该参数指定了将被创建的对象的种类。
ExternalClusterManager、TaskScheduler和SchedulerBackend的实现即为抽象工厂模式。
- 适合场景
在以下情况可以考虑使用抽象工厂模式:
- 一个系统要独立于它的产品的创建、组合和表示时。
- 一个系统要由多个产品系列中的一个来配置时。
- 需要强调一系列相关的产品对象的设计以便进行联合使用时。
- 提供一个产品类库,而只想显示它们的接口而不是实现时。
- 优点
- 分离了具体的类:具体产品从客户代码中被分离出来
- 容易改变产品的系列
- 有利于产品的一致性:将一个系列的产品族统一到一起创建
- 缺点
在产品族中扩展新的产品是很困难的,它需要修改抽象工厂的接口
- 相关模式
AbstractFactory类通常用工厂方法实现,也可以用Prototype实现。