Java设计模式 三十二 工厂模式 + 抽象工厂模式

工厂模式 + 抽象工厂模式

工厂模式(Factory Pattern)和抽象工厂模式(Abstract Factory Pattern)都属于创建型设计模式,它们的目的是帮助我们创建对象,但在应用场景和灵活性上有所不同。结合这两种模式可以更好地管理对象的创建,尤其是在需要管理一组相关或相互依赖的对象时。

  • 工厂模式(Factory Pattern)是一种创建对象的设计模式,它提供了一个用于创建对象的接口,但由子类决定实例化哪个类。工厂模式主要分为简单工厂模式、工厂方法模式和抽象工厂模式。

  • 抽象工厂模式(Abstract Factory Pattern)则提供了一个接口,用于创建一系列相关的对象,而不需要明确指定具体的类。抽象工厂模式将一组相关的产品类的创建过程封装起来,使得客户端可以通过抽象的接口来操作,而无需关心具体的产品如何创建。

结合这两者,可以在工厂模式的基础上进一步扩展,允许一个工厂创建一组相关的对象,从而形成一个更加灵活且可扩展的对象创建机制。


1. 场景说明

结合工厂模式抽象工厂模式的场景通常出现在以下情况:

  1. 需要创建一系列相关或相互依赖的对象: 在系统中,如果需要多个相关对象协作,可以使用抽象工厂来管理这些对象的创建。
  2. 不希望在客户端代码中显式地指定产品类别: 客户端通过抽象工厂接口来获取对象,避免了直接依赖具体的产品实现。
  3. 产品族: 如果系统需要支持多个产品族(例如,不同操作系统下的UI组件),抽象工厂模式可以更好地管理不同产品族的创建。

2. 示例场景:图形界面库(GUI)

假设我们需要创建一个跨平台的图形界面库,支持不同平台的UI控件(如按钮、文本框)。每个平台有不同的UI实现,但它们的接口是一致的。我们可以使用工厂模式创建不同类型的控件(如按钮、文本框),而使用抽象工厂模式来提供一个平台相关的控件集合(如Windows控件集、Mac控件集)。


(1) 产品接口:按钮和文本框

我们首先定义按钮(Button)和文本框(TextField)的接口,这些控件的具体实现会根据平台不同而有所不同。

// 按钮接口
public interface Button {
    void render();
    void onClick();
}

// 文本框接口
public interface TextField {
    void render();
    void onType();
}

(2) 具体产品:Windows平台按钮和文本框

对于Windows平台,我们实现按钮和文本框。

// 具体产品:Windows按钮
public class WindowsButton implements Button {
    @Override
    public void render() {
        System.out.println("Rendering Windows Button");
    }

    @Override
    public void onClick() {
        System.out.println("Click event for Windows Button");
    }
}

// 具体产品:Windows文本框
public class WindowsTextField implements TextField {
    @Override
    public void render() {
        System.out.println("Rendering Windows TextField");
    }

    @Override
    public void onType() {
        System.out.println("Typing in Windows TextField");
    }
}

(3) 具体产品:Mac平台按钮和文本框

对于Mac平台,我们也提供相应的按钮和文本框实现。

// 具体产品:Mac按钮
public class MacButton implements Button {
    @Override
    public void render() {
        System.out.println("Rendering Mac Button");
    }

    @Override
    public void onClick() {
        System.out.println("Click event for Mac Button");
    }
}

// 具体产品:Mac文本框
public class MacTextField implements TextField {
    @Override
    public void render() {
        System.out.println("Rendering Mac TextField");
    }

    @Override
    public void onType() {
        System.out.println("Typing in Mac TextField");
    }
}

(4) 抽象工厂:UI工厂

现在,我们定义一个抽象工厂接口,它提供了创建不同控件的接口。

// 抽象工厂接口:UI工厂
public interface UIFactory {
    Button createButton();
    TextField createTextField();
}

(5) 具体工厂:WindowsUI工厂和MacUI工厂

根据平台的不同,我们创建具体的工厂实现,每个工厂负责创建一系列特定的控件。

// 具体工厂:WindowsUI工厂
public class WindowsUIFactory implements UIFactory {
    @Override
    public Button createButton() {
        return new WindowsButton();  // 创建Windows按钮
    }

    @Override
    public TextField createTextField() {
        return new WindowsTextField();  // 创建Windows文本框
    }
}
// 具体工厂:MacUI工厂
public class MacUIFactory implements UIFactory {
    @Override
    public Button createButton() {
        return new MacButton();  // 创建Mac按钮
    }

    @Override
    public TextField createTextField() {
        return new MacTextField();  // 创建Mac文本框
    }
}

(6) 客户端代码

客户端代码通过抽象工厂来获取控件,而不关心具体的实现。我们只需要根据用户的操作系统来选择合适的工厂。

public class Client {
    private Button button;
    private TextField textField;

    // 使用抽象工厂获取控件
    public Client(UIFactory uiFactory) {
        this.button = uiFactory.createButton();
        this.textField = uiFactory.createTextField();
    }

    public void renderUI() {
        button.render();  // 渲染按钮
        textField.render();  // 渲染文本框
    }

    public void handleEvents() {
        button.onClick();  // 处理按钮点击事件
        textField.onType();  // 处理文本框输入事件
    }

    public static void main(String[] args) {
        // 选择UI工厂,假设客户端运行在Windows平台
        UIFactory factory = new WindowsUIFactory();

        Client client = new Client(factory);
        client.renderUI();
        client.handleEvents();
    }
}

运行结果(在Windows平台下运行):
Rendering Windows Button
Rendering Windows TextField
Click event for Windows Button
Typing in Windows TextField

3. 优点

工厂模式的优势:
  1. 简化对象创建: 工厂模式通过封装对象创建的过程,隐藏了创建的复杂性,客户端只需要知道如何通过工厂获取对象。
  2. 增强灵活性: 使用工厂模式后,客户端可以选择不同的工厂(即不同的创建方式),而无需修改现有代码。
  3. 易于扩展: 如果需要增加新的产品类(如新的控件类型),只需添加新的工厂和产品类即可,符合开闭原则。
抽象工厂模式的优势:
  1. 产品族支持: 抽象工厂模式特别适合用于需要创建一系列相关产品(如一组UI控件)的场景。每个工厂负责创建一个产品族,确保一组相关产品的一致性。
  2. 解耦: 客户端与具体的产品实现解耦,只关心产品的接口,具体实现由工厂负责。客户端无需了解产品的具体实现类。
  3. 产品组合: 如果某个产品族的所有产品都是由工厂创建的,确保所有产品都能正常工作并协同工作。
组合的优势:
  1. 创建复杂对象: 工厂模式和抽象工厂模式的结合可以更好地处理复杂对象的创建。每个工厂负责创建一组相互关联的对象,客户端只需要通过工厂接口进行交互。
  2. 支持不同产品族: 在多平台的场景下,抽象工厂可以根据不同的操作系统或环境选择合适的产品族(如Windows UI或Mac UI),使得整个系统能够无缝适配不同的环境。

4. 缺点

  1. 增加系统复杂性: 引入抽象工厂会导致系统中增加许多工厂类和产品类,增加了代码的复杂性。
  2. 产品扩展困难: 如果产品种类比较多或者有多层嵌套的产品族时,可能会导致工厂类和产品类的层次结构变得复杂。
  3. 代码冗长: 在某些简单场景下,使用抽象工厂模式可能会导致不必要的代码冗长,简单的工厂模式即可满足需求。

5. 应用场景

  1. 跨平台应用: 在开发跨平台应用时,使用抽象工厂模式可以根据不同的操作系统选择不同的UI控件集合,确保控件一致性。
  2. 产品族: 如果系统中需要支持多种产品族(如Windows产品族、Mac产品族),抽象工厂模式可以确保每个产品族的一致性。
  3. 多种操作系统支持: 在需要支持不同操作系统的应用中(如桌面应用或游戏引擎),可以使用工厂模式和抽象工厂模式来创建操作系统相关的对象。

6. 总结

通过将工厂模式抽象工厂模式结合使用,我们能够实现更加灵活和可扩展的对象创建机制。工厂模式适合简单的对象创建,而抽象工厂模式则可以帮助我们创建一系列相关或依赖的对象。在多平台、产品族等场景下,组合这两种模式可以有效地管理和扩展系统的创建逻辑。

你可能感兴趣的:(设计模式,java,设计模式,抽象工厂模式)