设计模式:抽象工厂模式

意图

抽象工厂模式(Abstract Factory)是一种创建型设计模式它能创建一系列相关的对象而无需指定其具体类

解决方案

首先,抽象工厂模式建议为系列中的每件产品明确声明接口。然后,确保所有产品变体都继承这些接口。 

接下来,我们需要声明抽象工厂——包含系列中所有产品构造方法的接口。这些方法必须返回抽象产品类型,即我们之前抽取的那些接口。

对于系列产品的每个变体,我们都将基于 抽象工厂接口创建不同的工厂类。每个工厂类都只能返回特定类别的产品。

客户端代码可以通过相应的抽象接口调用工厂和产品类。你无需修改实际客户端代码,就能更改传递给客户端的工厂类,也能更改客户端代码接收的产品变体。

抽象工厂模式结构

抽象工厂设计模式

抽象产品 Abstract Product 为构成系列产品的一组不同但相关的产品声明接口

具体产品 Concrete Product) 是抽象产品的多种不同类型实现。所有变体都必须实现相应的抽象产品。

抽象工厂 Abstract Factory 接口声明了一组创建各种抽象产品的方法

具体工厂 Concrete Factory) 实现抽象工厂的构建方法。每个具体工厂都对应特定产品变体,且仅创建此种产品变体。

尽管具体工厂会对具体产品进行初始化,其构建方法签名必须返回相应的抽象产品。这样,使用工厂类的客户端代码就不会与工厂创建的特定产品变体耦合。客户端 Client)只需通过抽象接口调用工厂和产品对象,就能与任何具体工厂/产品变体交互。

抽象工厂模式适合应用场景

  • 如果代码需要与多个不同系列的相关产品交互但是由于无法提前获取相关信息或者出于对未来扩展性的考虑你不希望代码基于产品的具体类进行构建在这种情况下你可以使用抽象工厂

 抽象工厂为你提供了一个接口可用于创建每个系列产品的对象只要代码通过该接口创建对象那么你就不会生成与应用程序已生成的产品类型不一致的产品

  •  如果你有一个基于一组工厂方法的类且其主要功能因此变得不明确那么在这种情况下可以考虑使用抽象工厂模式

 在设计良好的程序中每个类仅负责一件事如果一个类与多种类型产品交互就可以考虑将工厂方法抽取到独立的工厂类或具备完整功能的抽象工厂类中

抽象工厂模式优缺点

优点:

  • 你可以确保同一工厂生成的产品相互匹配
  •  你可以避免客户端和具体产品代码的耦合
  •  单一职责原则你可以将产品生成代码抽取到同一位置使得代码易于维护
  •  开闭原则向应用程序中引入新产品变体时你无需修改客户端代码

缺点:

由于采用该模式需要向应用中引入众多接口和类代码可能会比之前更加复杂

与其他模式的关系

在 Java 中使用模式

使用示例抽象工厂模式在 Java 代码中很常见许多框架和程序库会将它作为扩展和自定义其标准组件的一种方式

以下是来自核心 Java 程序库的一些示例

示例代码

抽象产品 Abstract Product

public interface Button {
    void render();
}
public interface Checkbox {
    void render();
}

具体产品 Concrete Product)

public class LinuxButton implements Button {
    @Override
    public void render() {
        System.out.println("Render Button in Linux system");
    }
}
public class WindowsButton implements Button {
    @Override
    public void render() {
        System.out.println("Render Button in Windows system");
    }
}

 

public class LinuxCheckbox implements Checkbox {
    @Override
    public void render() {
        System.out.println("Render Checkbox in Linux system");
    }
}
public class WindowsCheckbox implements Checkbox {
    @Override
    public void render() {
        System.out.println("Render Checkbox in Windows system");
    }
}

抽象工厂 Abstract Factory)

public interface GUIFactory {
    Button createButton();
    Checkbox createCheckbox();
}

具体工厂 Concrete Factory)

public class LinuxFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new LinuxButton();
    }

    @Override
    public Checkbox createCheckbox() {
        return new LinuxCheckbox();
    }
}
public class WindowsFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new WindowsButton();
    }

    @Override
    public Checkbox createCheckbox() {
        return new WindowsCheckbox();
    }
}

客户端 Client)

public class Client {
    public static void main(String[] args) {
        GUIFactory factory;
        if (System.getProperty("os.name").contains("Windows")) {
            factory = new WindowsFactory();
        } else {
            factory = new LinuxFactory();
        }
        Button button = factory.createButton();
        Checkbox checkbox = factory.createCheckbox();

        button.render();
        checkbox.render();
    }
}