Java设计模式之抽象工厂模式(Abstract Factory)

65 阅读2分钟

抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,用于创建一系列相关或依赖对象的家族,而不需指定具体类。这种模式提供了一种方式,让系统在不指定具体类的情况下,通过接口来创建一系列相关对象。

抽象工厂模式包含以下几个关键角色:

  1. AbstractFactory(抽象工厂) :声明了一组创建产品的方法,每一个方法对应一个产品等级(Product Family)。
  2. ConcreteFactory(具体工厂) :实现抽象工厂声明的接口以创建具体的产品。
  3. AbstractProduct(抽象产品) :定义了产品的接口,是产品家族的抽象。
  4. ConcreteProduct(具体产品) :实现了抽象产品接口的具体类。
  5. Client(客户类) :使用抽象工厂来创建产品。

抽象工厂模式的典型代码结构如下:

// 抽象产品A
interface ProductA {
    void use();
}

// 具体产品A1
class ConcreteProductA1 implements ProductA {
    public void use() {
        System.out.println("Using ConcreteProductA1");
    }
}

// 抽象产品B
interface ProductB {
    void use();
}

// 具体产品B1
class ConcreteProductB1 implements ProductB {
    public void use() {
        System.out.println("Using ConcreteProductB1");
    }
}

// 抽象工厂
interface AbstractFactory {
    ProductA createProductA();
    ProductB createProductB();
}

// 具体工厂1
class ConcreteFactory1 implements AbstractFactory {
    public ProductA createProductA() {
        return new ConcreteProductA1();
    }

    public ProductB createProductB() {
        // 可以创建具体产品B1
        return new ConcreteProductB1();
    }
}

// 客户类
class Client {
    AbstractFactory factory;

    public Client(AbstractFactory factory) {
        this.factory = factory;
    }

    public void getClient() {
        ProductA productA = factory.createProductA();
        ProductB productB = factory.createProductB();
        productA.use();
        productB.use();
    }
}

使用抽象工厂模式的示例:

public class AbstractFactoryDemo {
    public static void main(String[] args) {
        AbstractFactory factory = new ConcreteFactory1();
        Client client = new Client(factory);
        client.getClient();
    }
}

输出结果:

Using ConcreteProductA1
Using ConcreteProductB1

抽象工厂模式的优点包括:

  • 隔离复杂性:客户端不需要知道具体的类是如何实现的。
  • 扩展性:增加一个新的产品族时,不需要修改已有的代码,只需要添加相应的具体工厂和具体产品类。
  • 解耦:将类的实例化操作从使用类中分离出来。

抽象工厂模式的缺点包括:

  • 增加新的产品等级结构困难:需要对工厂接口及其所有子类进行修改。

抽象工厂模式适用于以下场景:

  • 当需要创建的产品族是相互关联的,且希望客户端不需要知道具体的类是如何实现的。
  • 当一个系统不应当依赖于具体的类,而是基于接口或抽象类来工作。
  • 当需要强调一系列相关的产品对象的设计以便进行联合使用时。