Skip to content

抽象工厂模式 (Abstract Factory Pattern) ​

模式定义 ​

抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。它是工厂方法模式的升级版,用于创建产品族。

核心概念 ​

  • 产品族 (Product Family): 由同一个工厂创建的一组相关产品
  • 产品等级 (Product Hierarchy): 同一产品的不同实现

实现示例:跨平台 UI ​

产品接口 ​

java
// 按钮产品接口
public interface Button {
    void render();
    void onClick(Runnable action);
}

// 文本框产品接口
public interface TextField {
    void render();
    void setText(String text);
}

// 复选框产品接口
public interface Checkbox {
    void render();
    void setChecked(boolean checked);
}

Windows 产品族 ​

java
// Windows 按钮
public class WindowsButton implements Button {
    @Override
    public void render() {
        System.out.println("渲染 Windows 风格按钮");
    }

    @Override
    public void onClick(Runnable action) {
        System.out.println("Windows 按钮点击事件");
        action.run();
    }
}

// Windows 文本框
public class WindowsTextField implements TextField {
    @Override
    public void render() {
        System.out.println("渲染 Windows 风格文本框");
    }

    @Override
    public void setText(String text) {
        System.out.println("Windows 文本框设置内容: " + text);
    }
}

// Windows 复选框
public class WindowsCheckbox implements Checkbox {
    @Override
    public void render() {
        System.out.println("渲染 Windows 风格复选框");
    }

    @Override
    public void setChecked(boolean checked) {
        System.out.println("Windows 复选框状态: " + (checked ? "选中" : "未选中"));
    }
}

macOS 产品族 ​

java
// macOS 按钮
public class MacButton implements Button {
    @Override
    public void render() {
        System.out.println("渲染 macOS 风格按钮");
    }

    @Override
    public void onClick(Runnable action) {
        System.out.println("macOS 按钮点击事件");
        action.run();
    }
}

// macOS 文本框
public class MacTextField implements TextField {
    @Override
    public void render() {
        System.out.println("渲染 macOS 风格文本框");
    }

    @Override
    public void setText(String text) {
        System.out.println("macOS 文本框设置内容: " + text);
    }
}

// macOS 复选框
public class MacCheckbox implements Checkbox {
    @Override
    public void render() {
        System.out.println("渲染 macOS 风格复选框");
    }

    @Override
    public void setChecked(boolean checked) {
        System.out.println("macOS 复选框状态: " + (checked ? "选中" : "未选中"));
    }
}

抽象工厂接口 ​

java
// UI 工厂接口
public interface UIFactory {
    Button createButton();
    TextField createTextField();
    Checkbox createCheckbox();
}

具体工厂 ​

java
// Windows UI 工厂
public class WindowsUIFactory implements UIFactory {
    @Override
    public Button createButton() {
        return new WindowsButton();
    }

    @Override
    public TextField createTextField() {
        return new WindowsTextField();
    }

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

// macOS UI 工厂
public class MacUIFactory implements UIFactory {
    @Override
    public Button createButton() {
        return new MacButton();
    }

    @Override
    public TextField createTextField() {
        return new MacTextField();
    }

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

客户端代码 ​

java
// 表单组件,使用抽象工厂创建 UI 元素
public class Form {
    private final Button button;
    private final TextField textField;
    private final Checkbox checkbox;

    public Form(UIFactory factory) {
        this.button = factory.createButton();
        this.textField = factory.createTextField();
        this.checkbox = factory.createCheckbox();
    }

    public void render() {
        System.out.println("=== 渲染表单 ===");
        textField.render();
        checkbox.render();
        button.render();
    }

    public void submit() {
        button.onClick(() -> {
            System.out.println("表单提交成功!");
        });
    }
}

// 测试代码
public class AbstractFactoryDemo {
    public static void main(String[] args) {
        // 根据操作系统选择工厂
        String os = System.getProperty("os.name").toLowerCase();
        UIFactory factory;

        if (os.contains("win")) {
            factory = new WindowsUIFactory();
        } else if (os.contains("mac")) {
            factory = new MacUIFactory();
        } else {
            factory = new WindowsUIFactory(); // 默认
        }

        // 创建表单
        Form form = new Form(factory);
        form.render();
        form.submit();
    }
}

运行时动态切换工厂 ​

java
// 工厂枚举,支持运行时选择
public enum UIFactoryType {
    WINDOWS, MAC
}

// 工厂工厂,根据枚举创建具体工厂
public class UIFactoryCreator {
    public static UIFactory createFactory(UIFactoryType type) {
        switch (type) {
            case WINDOWS:
                return new WindowsUIFactory();
            case MAC:
                return new MacUIFactory();
            default:
                throw new IllegalArgumentException("不支持的 UI 类型: " + type);
        }
    }
}

// 使用
UIFactory factory = UIFactoryCreator.createFactory(UIFactoryType.MAC);
Form form = new Form(factory);

JDBC 中的抽象工厂 ​

java
// JDBC 连接工厂就是典型的抽象工厂模式
Connection connection = DriverManager.getConnection(url, user, password);
// 不同的 JDBC 驱动实现返回不同的 Connection、Statement、ResultSet 等产品族

产品族 vs 产品等级 ​

产品族        按钮        文本框      复选框
Windows      WindowsButton  WindowsTextField  WindowsCheckbox
macOS        MacButton      MacTextField      MacCheckbox
Linux        LinuxButton    LinuxTextField    LinuxCheckbox

每一行是一个产品族,每一列是一个产品等级。抽象工厂保证同一工厂创建的产品属于同一产品族。

优缺点 ​

优点:

  • 保证同族产品的兼容性
  • 符合开闭原则,新增产品族容易
  • 隔离具体类,客户端只依赖接口

缺点:

  • 新增产品类型困难(需要修改所有工厂接口)
  • 类数量多,系统复杂度高

实际应用 ​

  • Java GUI: AWT/Swing 的跨平台 UI
  • 数据库访问: 不同数据库的 Connection、Statement、ResultSet
  • 游戏引擎: 不同平台的渲染、音频、输入设备
  • 换肤功能: 不同皮肤主题下的 UI 组件