抽象工厂

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

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

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

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

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

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

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

buttons: 第一个产品层次结构
Button接口
public interface Button {
    void paint();
}
MacOSButton实现类
public class MacOSButton implements Button {

    @Override
    public void paint() {
        System.out.println("You have created MacOSButton.");
    }
}
WindowsButton实现类
public class WindowsButton implements Button {

    @Override
    public void paint() {
        System.out.println("You have created WindowsButton.");
    }
}
checkboxes: 第二个产品层次结构
CheckBox接口
public interface Checkbox {
    void paint();
}
MacOSCheckBox接口
public class MacOSCheckbox implements Checkbox {

    @Override
    public void paint() {
        System.out.println("You have created MacOSCheckbox.");
    }
}
WindowsCheckBox接口
public class WindowsCheckbox implements Checkbox {

    @Override
    public void paint() {
        System.out.println("You have created WindowsCheckbox.");
    }
}
GUIFactory: 抽象工厂
public interface GUIFactory {
    Button createButton();
    Checkbox createCheckbox();
}
MacOSFactory: 具体工厂 mac­OS
public class MacOSFactory implements GUIFactory {

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

    @Override
    public Checkbox createCheckbox() {
        return new MacOSCheckbox();
    }
}
WindowFactory: 具体工厂Windows
public class WindowsFactory implements GUIFactory {

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

    @Override
    public Checkbox createCheckbox() {
        return new WindowsCheckbox();
    }
}
客户段代码
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();
    }
}
测试
public class Demo {
    private static Application configureApplication() {
        Application app;
        GUIFactory factory;
        String osName = System.getProperty("os.name").toLowerCase();
        if (osName.contains("mac")) {
            factory = new MacOSFactory();
        } else {
            factory = new WindowsFactory();
        }
        app = new Application(factory);
        return app;
    }

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