跳转到内容

Java抽象工厂模式

来自代码酷

Java抽象工厂模式[编辑 | 编辑源代码]

抽象工厂模式(Abstract Factory Pattern)是Java设计模式中一种创建型模式,它提供了一种方式来创建一系列相关或相互依赖的对象,而无需指定它们的具体类。该模式适用于需要创建多个产品族(即一组相关产品)的场景,同时确保客户端代码与具体实现解耦。

介绍[编辑 | 编辑源代码]

抽象工厂模式扩展了工厂方法模式,但它不是创建单一产品,而是创建多个产品族。例如,一个GUI库可能需要创建跨平台的按钮、文本框和对话框,而抽象工厂可以确保同一风格(如Windows或Mac风格)的所有组件被一起创建。

核心概念[编辑 | 编辑源代码]

  • 抽象工厂(Abstract Factory):声明创建产品对象的接口。
  • 具体工厂(Concrete Factory):实现抽象工厂接口,创建具体产品。
  • 抽象产品(Abstract Product):声明产品的接口。
  • 具体产品(Concrete Product):实现抽象产品接口的具体类。

结构[编辑 | 编辑源代码]

classDiagram class AbstractFactory { +createProductA(): AbstractProductA +createProductB(): AbstractProductB } class ConcreteFactory1 { +createProductA(): AbstractProductA +createProductB(): AbstractProductB } class ConcreteFactory2 { +createProductA(): AbstractProductA +createProductB(): AbstractProductB } class AbstractProductA { +operationA(): void } class AbstractProductB { +operationB(): void } class ProductA1 { +operationA(): void } class ProductB1 { +operationB(): void } class ProductA2 { +operationA(): void } class ProductB2 { +operationB(): void } AbstractFactory <|-- ConcreteFactory1 AbstractFactory <|-- ConcreteFactory2 AbstractProductA <|-- ProductA1 AbstractProductA <|-- ProductA2 AbstractProductB <|-- ProductB1 AbstractProductB <|-- ProductB2 ConcreteFactory1 --> ProductA1 ConcreteFactory1 --> ProductB1 ConcreteFactory2 --> ProductA2 ConcreteFactory2 --> ProductB2

代码示例[编辑 | 编辑源代码]

以下是一个跨平台UI组件(按钮和复选框)的抽象工厂实现:

抽象产品[编辑 | 编辑源代码]

// 抽象产品:按钮
interface Button {
    void render();
}

// 抽象产品:复选框
interface Checkbox {
    void render();
}

具体产品[编辑 | 编辑源代码]

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

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

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

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

抽象工厂[编辑 | 编辑源代码]

interface GUIFactory {
    Button createButton();
    Checkbox createCheckbox();
}

具体工厂[编辑 | 编辑源代码]

// Windows风格工厂
class WindowsFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new WindowsButton();
    }

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

// Mac风格工厂
class MacFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new MacButton();
    }

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

客户端代码[编辑 | 编辑源代码]

public class Application {
    private Button button;
    private Checkbox checkbox;

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

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

    public static void main(String[] args) {
        // 创建Windows风格UI
        Application app1 = new Application(new WindowsFactory());
        app1.render();

        // 创建Mac风格UI
        Application app2 = new Application(new MacFactory());
        app2.render();
    }
}

输出[编辑 | 编辑源代码]

渲染Windows风格按钮
渲染Windows风格复选框
渲染Mac风格按钮
渲染Mac风格复选框

实际应用场景[编辑 | 编辑源代码]

抽象工厂模式在以下场景中特别有用:

  • 需要创建一组相关或依赖的对象(如UI组件、数据库连接等)。
  • 系统需要独立于其产品的创建、组合和表示方式。
  • 需要提供多个产品族,但客户端只使用其中一族。

真实案例[编辑 | 编辑源代码]

1. 跨平台UI框架(如JavaFX、Swing)使用抽象工厂确保同一风格的组件被创建。 2. 数据库访问层可以针对不同数据库(MySQL、PostgreSQL)提供各自的工厂。 3. 游戏开发中为不同角色创建配套的武器、装备和技能。

优缺点[编辑 | 编辑源代码]

优点[编辑 | 编辑源代码]

  • 确保产品兼容性(同一族产品一起工作)。
  • 客户端代码与具体类解耦。
  • 符合开闭原则(新增产品族无需修改现有代码)。

缺点[编辑 | 编辑源代码]

  • 新增产品种类(如新增一个Slider组件)需要修改所有工厂接口。
  • 代码复杂度较高,适合大型项目。

数学表示[编辑 | 编辑源代码]

抽象工厂可以形式化表示为: Factory={F1,F2,,Fn}Productk={Pk1,Pk2,,Pkm}Fi{P1i,P2i,,Pki} 其中:

  • Fi是具体工厂
  • Pki是第k个产品族的第i个实现

总结[编辑 | 编辑源代码]

抽象工厂模式是构建复杂系统的强大工具,尤其适合需要管理多个相关产品族的场景。通过将创建逻辑封装在工厂中,系统可以更灵活地切换产品系列(如从Windows切换到Mac风格),同时保持客户端代码的简洁性。