简单工厂、工厂方法模式、抽象工厂模式

简介

  • 简单工厂:适合单一产品、创建逻辑简单的场景,但不符合开闭原则。
  • 工厂方法:适合需要扩展多种具体产品的场景,符合开闭原则。
  • 抽象工厂:适合需要创建一组相关对象的场景,支持切换整个产品簇。

简单工厂模式

通过一个工厂类集中处理对象的创建逻辑,根据传入的参数决定创建哪一种产品类的实例。

java 复制代码
// 抽象产品
interface Product {
    void use();
}

// 具体产品A
class ConcreteProductA implements Product {
    public void use() {
        System.out.println("Using Product A");
    }
}

// 具体产品B
class ConcreteProductB implements Product {
    public void use() {
        System.out.println("Using Product B");
    }
}

// 简单工厂
class SimpleFactory {
    public Product createProduct(String type) {
        switch (type) {
            case "A":
                return new ConcreteProductA();
            case "B":
                return new ConcreteProductB();
            default:
                throw new IllegalArgumentException("Unknown product type");
        }
    }
}

// 客户端调用
public class Client {
    public static void main(String[] args) {
        SimpleFactory factory = new SimpleFactory();
        Product product = factory.createProduct("A");
        product.use(); // 输出: Using Product A
    }
}

工厂方法模式

定义了一个用于创建对象的接口,但让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

核心结构:

  • Product(抽象产品):定义产品的公共接口。
  • ConcreteProduct(具体产品):实现 Product 接口的具体类。
  • Factory(抽象工厂):声明一个工厂方法,用于创建 Product 对象。
  • ConcreteFactory(具体工厂):实现工厂方法,返回一个具体的 ConcreteProduct 实例。
java 复制代码
// 抽象产品
interface Product {
    void use();
}

// 具体产品A
class ConcreteProductA implements Product {
    public void use() {
        System.out.println("Using Product A");
    }
}

// 具体产品B
class ConcreteProductB implements Product {
    public void use() {
        System.out.println("Using Product B");
    }
}

// 抽象工厂
abstract class Factory {
    // 工厂方法
    abstract Product createProduct();

    // 使用产品的方法
    void doSomething() {
        Product product = createProduct();
        product.use();
    }
}

// 具体工厂A
class FactoryA extends Factory {
    @Override
    Product createProduct() {
        return new ConcreteProductA();
    }
}

// 具体工厂B
class FactoryB extends Factory {
    @Override
    Product createProduct() {
        return new ConcreteProductB();
    }
}

// 客户端调用
public class Client {
    public static void main(String[] args) {
        Factory factoryA = new FactoryA();
        factoryA.doSomething(); // 输出: Using Product A

        Factory factoryB = new FactoryB();
        factoryB.doSomething(); // 输出: Using Product B
    }
}

抽象工厂模式

提供一个接口,用于创建一组相关或依赖对象的家族,而无需指定具体类。 这在需要为不同的"产品族"提供统一的创建方式时非常有用,比如: 不同操作系统下的 UI 控件(按钮、文本框等); 不同风格的主题(深色、浅色); 多平台客户端(PC、移动端)所需的一整套组件。

接口和抽象类都可以实现抽象工厂模式, 但更倾向于使用 接口(interface) 来实现抽象工厂,因为: 更符合面向接口编程的思想; 支持多继承; 可以配合默认方法提供更灵活的设计。

下面是一个完整的 抽象工厂模式(Abstract Factory Pattern) 的 Java 示例实现,涵盖了:

  • 抽象工厂接口
  • 具体工厂类
  • 抽象产品接口
  • 具体产品类
  • 客户端调用

这个例子以"不同风格的 UI 控件"为例:比如 Windows 风格和 Mac 风格的按钮和文本框。


1. 定义抽象产品接口

Button.java - 按钮接口

java 复制代码
public interface Button {
    void render();
}

TextBox.java - 文本框接口

java 复制代码
public interface TextBox {
    void render();
}

2. 实现具体产品类

WindowsButton.java

java 复制代码
class WindowsButton implements Button {
    public void render() {
        System.out.println("Render a Windows style button.");
    }
}

MacButton.java

java 复制代码
class MacButton implements Button {
    public void render() {
        System.out.println("Render a Mac style button.");
    }
}

WindowsTextBox.java

java 复制代码
class WindowsTextBox implements TextBox {
    public void render() {
        System.out.println("Render a Windows style text box.");
    }
}

MacTextBox.java

java 复制代码
class MacTextBox implements TextBox {
    public void render() {
        System.out.println("Render a Mac style text box.");
    }
}

3. 定义抽象工厂接口

UIFactory.java

java 复制代码
public interface UIFactory {
    Button createButton();   // 创建按钮
    TextBox createTextBox(); // 创建文本框
}

4. 实现具体工厂类

WindowsFactory.java

java 复制代码
class WindowsFactory implements UIFactory {
    public Button createButton() {
        return new WindowsButton();
    }

    public TextBox createTextBox() {
        return new WindowsTextBox();
    }
}

MacFactory.java

java 复制代码
class MacFactory implements UIFactory {
    public Button createButton() {
        return new MacButton();
    }

    public TextBox createTextBox() {
        return new MacTextBox();
    }
}

5. 编写客户端代码使用抽象工厂

Client.java

java 复制代码
public class Client {
    private Button button;
    private TextBox textBox;

    public Client(UIFactory factory) {
        this.button = factory.createButton();
        this.textBox = factory.createTextBox();
    }

    public void renderUI() {
        button.render();
        textBox.render();
    }

    public static void main(String[] args) {
        String osType = "mac"; // 可改为 "windows"

        UIFactory factory;
        if ("windows".equalsIgnoreCase(osType)) {
            factory = new WindowsFactory();
        } else {
            factory = new MacFactory();
        }

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

输出结果(当 osType = "mac")

css 复制代码
Render a Mac style button.
Render a Mac style text box.

总结
角色 类名
抽象产品A Button
抽象产品B TextBox
具体产品A1 WindowsButton
具体产品A2 MacButton
具体产品B1 WindowsTextBox
具体产品B2 MacTextBox
抽象工厂 UIFactory
具体工厂1 WindowsFactory
具体工厂2 MacFactory

扩展建议
  • 如果需要新增一个控件类型(如 ComboBox),只需在抽象工厂中添加新方法,并在所有具体工厂中实现。
  • 若使用 Java 8+,可在接口中提供默认实现,提高灵活性。
  • 结合 Spring 或其他 IOC 框架可以实现更优雅的解耦与配置切换。
相关推荐
序安InToo19 分钟前
第6课|注释与代码风格
后端·操作系统·嵌入式
xyy12319 分钟前
C#: Newtonsoft.Json 到 System.Text.Json 迁移避坑指南
后端
洋洋技术笔记22 分钟前
Spring Boot Web MVC配置详解
spring boot·后端
JxWang0522 分钟前
VS Code 配置 Markdown 环境
后端
navms25 分钟前
搞懂线程池,先把 Worker 机制啃明白
后端
JxWang0525 分钟前
离线数仓的优化及重构
后端
Nyarlathotep011326 分钟前
gin01:初探gin的启动
后端·go
JxWang0527 分钟前
安卓手机配置通用多屏协同及自动化脚本
后端
JxWang0528 分钟前
Windows Terminal 配置 oh-my-posh
后端
SimonKing44 分钟前
OpenCode AI编程助手如何添加Skills,优化项目!
java·后端·程序员