🇨🇳🐲🎉 本网站的中文版本尚处早期开发阶段。如果您发现其中存在错字、纰漏或其他任何问题,请随时联系 [email protected] 向我反馈。
抽象工厂

抽象工厂在 Java 中的实现

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

抽象工厂定义了用于创建不同产品的接口 但将实际的创建工作留给了具体工厂类 每个工厂类型都对应一个特定的产品变体

在创建产品时 客户端代码调用的是工厂对象的构建方法 而不是直接调用构造函数 new 操作符 由于一个工厂对应一种产品变体 因此它创建的所有产品都可相互兼容

客户端代码仅通过其抽象接口与工厂和产品进行交互 该接口允许同一客户端代码与不同产品进行交互 你只需创建一个具体工厂类并将其传递给客户端代码即可

如果你不清楚工厂 工厂方法抽象工厂模式之间的区别 请参阅工厂模式比较

进一步了解抽象工厂模式

在 Java 中使用模式

复杂度

流行度

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

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

识别方法 我们可以通过方法来识别该模式——其会返回一个工厂对象 接下来 工厂将被用于创建特定的子组件

跨平台 GUI 组件系列及其创建方式

在本例中 按钮和复选框将被作为产品 它们有两个变体 macOS 版和 Windows 版

抽象工厂定义了用于创建按钮和复选框的接口 而两个具体工厂都会返回同一变体的两个产品

客户端代码使用抽象接口与工厂和产品进行交互 同样的代码能与依赖于不同工厂对象类型的多种产品变体进行交互

buttons: 第一个产品层次结构

buttons/Button.java

package refactoring_guru.abstract_factory.example.buttons;

/**
 * Abstract Factory assumes that you have several families of products,
 * structured into separate class hierarchies (Button/Checkbox). All products of
 * the same family have the common interface.
 *
 * This is the common interface for buttons family.
 */
public interface Button {
    void paint();
}

buttons/MacOSButton.java

package refactoring_guru.abstract_factory.example.buttons;

/**
 * All products families have the same varieties (MacOS/Windows).
 *
 * This is a MacOS variant of a button.
 */
public class MacOSButton implements Button {

    @Override
    public void paint() {
        System.out.println("You have created MacOSButton.");
    }
}

buttons/WindowsButton.java

package refactoring_guru.abstract_factory.example.buttons;

/**
 * All products families have the same varieties (MacOS/Windows).
 *
 * This is another variant of a button.
 */
public class WindowsButton implements Button {

    @Override
    public void paint() {
        System.out.println("You have created WindowsButton.");
    }
}

checkboxes: 第二个产品层次结构

checkboxes/Checkbox.java

package refactoring_guru.abstract_factory.example.checkboxes;

/**
 * Checkboxes is the second product family. It has the same variants as buttons.
 */
public interface Checkbox {
    void paint();
}

checkboxes/MacOSCheckbox.java

package refactoring_guru.abstract_factory.example.checkboxes;

/**
 * All products families have the same varieties (MacOS/Windows).
 *
 * This is a variant of a checkbox.
 */
public class MacOSCheckbox implements Checkbox {

    @Override
    public void paint() {
        System.out.println("You have created MacOSCheckbox.");
    }
}

checkboxes/WindowsCheckbox.java

package refactoring_guru.abstract_factory.example.checkboxes;

/**
 * All products families have the same varieties (MacOS/Windows).
 *
 * This is another variant of a checkbox.
 */
public class WindowsCheckbox implements Checkbox {

    @Override
    public void paint() {
        System.out.println("You have created WindowsCheckbox.");
    }
}

factories

factories/GUIFactory.java: 抽象工厂

package refactoring_guru.abstract_factory.example.factories;

import refactoring_guru.abstract_factory.example.buttons.Button;
import refactoring_guru.abstract_factory.example.checkboxes.Checkbox;

/**
 * Abstract factory knows about all (abstract) product types.
 */
public interface GUIFactory {
    Button createButton();
    Checkbox createCheckbox();
}

factories/MacOSFactory.java: 具体工厂 mac­OS

package refactoring_guru.abstract_factory.example.factories;

import refactoring_guru.abstract_factory.example.buttons.Button;
import refactoring_guru.abstract_factory.example.buttons.MacOSButton;
import refactoring_guru.abstract_factory.example.checkboxes.Checkbox;
import refactoring_guru.abstract_factory.example.checkboxes.MacOSCheckbox;

/**
 * Each concrete factory extends basic factory and responsible for creating
 * products of a single variety.
 */
public class MacOSFactory implements GUIFactory {

    @Override
    public Button createButton() {
        return new MacOSButton();
    }

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

factories/WindowsFactory.java: 具体工厂 Windows

package refactoring_guru.abstract_factory.example.factories;

import refactoring_guru.abstract_factory.example.buttons.Button;
import refactoring_guru.abstract_factory.example.buttons.WindowsButton;
import refactoring_guru.abstract_factory.example.checkboxes.Checkbox;
import refactoring_guru.abstract_factory.example.checkboxes.WindowsCheckbox;

/**
 * Each concrete factory extends basic factory and responsible for creating
 * products of a single variety.
 */
public class WindowsFactory implements GUIFactory {

    @Override
    public Button createButton() {
        return new WindowsButton();
    }

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

app

app/Application.java: 客户端代码

package refactoring_guru.abstract_factory.example.app;

import refactoring_guru.abstract_factory.example.buttons.Button;
import refactoring_guru.abstract_factory.example.checkboxes.Checkbox;
import refactoring_guru.abstract_factory.example.factories.GUIFactory;

/**
 * Factory users don't care which concrete factory they use since they work with
 * factories and products through abstract interfaces.
 */
public class Application {
    private Button button;
    private Checkbox checkbox;

    public Application(GUIFactory factory) {
        button = factory.createButton();
        checkbox = factory.createCheckbox();
    }

    public void paint() {
        button.paint();
        checkbox.paint();
    }
}

Demo.java: 程序配置

package refactoring_guru.abstract_factory.example;

import refactoring_guru.abstract_factory.example.app.Application;
import refactoring_guru.abstract_factory.example.factories.GUIFactory;
import refactoring_guru.abstract_factory.example.factories.MacOSFactory;
import refactoring_guru.abstract_factory.example.factories.WindowsFactory;

/**
 * Demo class. Everything comes together here.
 */
public class Demo {

    /**
     * Application picks the factory type and creates it in run time (usually at
     * initialization stage), depending on the configuration or environment
     * variables.
     */
    private static Application configureApplication() {
        Application app;
        GUIFactory factory;
        String osName = System.getProperty("os.name").toLowerCase();
        if (osName.contains("mac")) {
            factory = new MacOSFactory();
            app = new Application(factory);
        } else {
            factory = new WindowsFactory();
            app = new Application(factory);
        }
        return app;
    }

    public static void main(String[] args) {
        Application app = configureApplication();
        app.paint();
    }
}

OutputDemo.txt: 执行结果

You create WindowsButton.
You created WindowsCheckbox.

抽象工厂在其他编程语言中的实现

抽象工厂在 C# 中的实现 抽象工厂在 PHP 中的实现 抽象工厂在 Python 中的实现 抽象工厂在 Ruby 中的实现 抽象工厂在 Swift 中的实现 抽象工厂在 TypeScript 中的实现