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

简介

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

简单工厂模式

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

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 框架可以实现更优雅的解耦与配置切换。
相关推荐
2302_809798321 小时前
【JavaWeb】Docker项目部署
java·运维·后端·青少年编程·docker·容器
zhojiew2 小时前
关于akka官方quickstart示例程序(scala)的记录
后端·scala
sclibingqing2 小时前
SpringBoot项目接口集中测试方法及实现
java·spring boot·后端
JohnYan3 小时前
Bun技术评估 - 03 HTTP Server
javascript·后端·bun
周末程序猿3 小时前
Linux高性能网络编程十谈|C++11实现22种高并发模型
后端·面试
ZHOU_WUYI3 小时前
Flask与Celery 项目应用(shared_task使用)
后端·python·flask
冒泡的肥皂4 小时前
强大的ANTLR4语法解析器入门demo
后端·搜索引擎·编程语言
IT_陈寒4 小时前
Element Plus 2.10.0 重磅发布!新增Splitter组件
前端·人工智能·后端
有梦想的攻城狮5 小时前
spring中的@RabbitListener注解详解
java·后端·spring·rabbitlistener