创建型模式之抽象工厂模式

x33g5p2x  于2022-02-12 转载在 其他  
字(3.0k)|赞(0)|评价(0)|浏览(180)

🥺问题

假设你正在开发一款家具商店模拟器。代码中包含这些类:

1.产品:椅子,沙发,咖啡桌

2.系列产品的不同变体。例如,你可以使用现代,维多利亚,装修风艺术等风格生成椅子,沙发和咖啡桌。

你需要设法单独生成每件家具对象,这样才能确保其风格一致。如果顾客收到的家具风格不一样,他们可不会开心。

此外,你也不希望在添加新产品或心风格时修改已有代码。家具供应商对于产品目录的更新非常频繁,你不会想在每次更新时都去修改核心代码。

😀解决方案

首先,抽象工厂模式建议为系列中的每件产品明确声明接口(例如椅子,沙发或咖啡桌)。然后,确保所有产品变体都继承这些接口。例如,所有风格的椅子都实现椅子接口;所有风格的咖啡桌都实现咖啡桌接口。

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

对于系列产品的每个变体,我们都将基于抽象工厂接口创建不同的工厂类。每个工厂类都只能返回特定类别的产品,例如:现代家具工厂只能创建现代椅子,现代沙发和现代咖啡桌。

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

1.抽象工厂模式(java案例)

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

抽象产品:按钮,复选框

具体产品:WindowsButton,MacOSButton,MacOSCheckbox,WinddowsCheckbox

buttons:第一个产品

buttons/Button.java

public interface Button {
    void paint();
}

buttons/MacOSButton.java

//具体产品实现抽象产品
public class MacOSButton implements Button {
    @Override
    public void paint() {
        System.out.println("You have created MacOSButton.");
    }
}

buttons/WindowsButton.java

public class WindowsButton implements Button {
	@Override
    public void paint() {
        System.out.println("You have created WindowsButton.");
    }
}
checkboxes:第二个产品

checkBoxes/Checkbox.java

public interface Checkbox {
    void paint();
}

checkboxes/MacOSCheckbox.java

public class MacOSCheckbox implements Checkbox {

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

checkboxes/WindowsCheckbox.java

public class WindowsCheckbox implements Checkbox {
    @Override
    public void paint() {
        System.out.println("You have created WindowsCheckbox.");
    }
}
factories:抽象工厂

factories/GUIFactory.java:抽象工厂

//抽象工厂中抽象方法的返回值为抽象产品类型
public interface GUIFactory {
    Button createButton();
    Checkbox createCheckbox();
}

factories/MacOSFactory.java:具体工厂

//具体工厂实现抽象工厂
public class MacOSFactory implements GUIFactory {

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

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

factories/WindowsFactory.java:具体工厂

public class WindowsFactory implements GUIFactory {

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

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

app/Application.java

//工厂用户不关心他们使用的是哪个工厂,因为他们和工厂一起工作,工厂和产品通过抽象接口。
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:程序配置
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();
            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();
    }
}

2.抽象工厂模式的优缺点

优点

1)确保同一个工厂生成的产品相互匹配

2)你可以避免客户端和具体产品代码的耦合

3)单一职责原则。你可以将产品生成代码抽取到同一位置,使得代码易于维护。

4)开闭原则。向应用程序引入新产品变体时,你无需修改客户端代码。

缺点

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

3.工厂模式的区别

1)简单工厂:使用一个工厂对象用来生产同一等级结构中的任意产品。(不支持扩展增加产品)

2)工厂方法:使用多个工厂对象用来生产同一等级结构中对应的固定产品。(支持扩展增加产品)

3)抽象工厂:使用多个工厂对象用来生产不同产品族的全部产品。(不支持扩展增加产品;支持增加产品族)

相关文章