Java案例中的抽象工厂怎么用?

wen java案例 2

Java抽象工厂模式详解

抽象工厂模式是一种创建型设计模式,它提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

Java案例中的抽象工厂怎么用?

核心概念

抽象工厂模式包含以下角色:

  • 抽象工厂 (AbstractFactory):声明创建抽象产品对象的操作接口
  • 具体工厂 (ConcreteFactory):实现创建具体产品对象的操作
  • 抽象产品 (AbstractProduct):声明一类产品的接口
  • 具体产品 (ConcreteProduct):实现抽象产品接口的具体对象
  • 客户端 (Client):仅使用抽象工厂和抽象产品声明的接口

实际案例:跨平台UI组件

假设我们要开发一个跨平台的UI框架,需要为不同操作系统(Windows、Mac)创建不同的按钮和文本框。

定义抽象产品接口

// 抽象产品:按钮
interface Button {
    void render();
    void onClick();
}
// 抽象产品:文本框
interface TextField {
    void display();
    void setText(String text);
    String getText();
}

实现具体产品

// Windows风格按钮
class WindowsButton implements Button {
    @Override
    public void render() {
        System.out.println("渲染Windows风格按钮");
    }
    @Override
    public void onClick() {
        System.out.println("Windows按钮被点击");
    }
}
// Mac风格按钮
class MacButton implements Button {
    @Override
    public void render() {
        System.out.println("渲染Mac风格按钮");
    }
    @Override
    public void onClick() {
        System.out.println("Mac按钮被点击");
    }
}
// Windows风格文本框
class WindowsTextField implements TextField {
    private String text;
    @Override
    public void display() {
        System.out.println("显示Windows文本框: " + text);
    }
    @Override
    public void setText(String text) {
        this.text = text;
    }
    @Override
    public String getText() {
        return text;
    }
}
// Mac风格文本框
class MacTextField implements TextField {
    private String text;
    @Override
    public void display() {
        System.out.println("显示Mac文本框: " + text);
    }
    @Override
    public void setText(String text) {
        this.text = text;
    }
    @Override
    public String getText() {
        return text;
    }
}

定义抽象工厂

// 抽象工厂
interface UIFactory {
    Button createButton();
    TextField createTextField();
}

实现具体工厂

// Windows工厂
class WindowsUIFactory implements UIFactory {
    @Override
    public Button createButton() {
        return new WindowsButton();
    }
    @Override
    public TextField createTextField() {
        return new WindowsTextField();
    }
}
// Mac工厂
class MacUIFactory implements UIFactory {
    @Override
    public Button createButton() {
        return new MacButton();
    }
    @Override
    public TextField createTextField() {
        return new MacTextField();
    }
}

客户端使用

public class Application {
    private Button button;
    private TextField textField;
    private UIFactory factory;
    public Application(UIFactory factory) {
        this.factory = factory;
        this.button = factory.createButton();
        this.textField = factory.createTextField();
    }
    public void run() {
        // 使用UI组件
        textField.setText("请输入内容");
        button.render();
        button.onClick();
        textField.display();
    }
    public static void main(String[] args) {
        // 根据配置选择工厂
        String os = "Windows"; // 实际可从配置或系统属性获取
        UIFactory factory;
        if (os.equalsIgnoreCase("Windows")) {
            factory = new WindowsUIFactory();
        } else {
            factory = new MacUIFactory();
        }
        Application app = new Application(factory);
        app.run();
    }
}

使用工厂方法模式简化(可选)

如果觉得抽象工厂过于复杂,也可以使用工厂方法模式来实现类似功能:

// 简单工厂方法
class SimpleUIFactory {
    public static Button createButton(String os) {
        if (os.equals("Windows")) {
            return new WindowsButton();
        } else {
            return new MacButton();
        }
    }
    public static TextField createTextField(String os) {
        if (os.equals("Windows")) {
            return new WindowsTextField();
        } else {
            return new MacTextField();
        }
    }
}

何时使用抽象工厂模式

  1. 需要创建一组相关对象:如UI组件、数据库连接
  2. 系统需要独立于产品的创建、组合和表示:客户端不需要知道具体产品类
  3. 系统需要更换产品家族:切换不同操作系统下的UI组件

优缺点

优点

  • 隔离具体产品类,客户端只与抽象接口交互
  • 易于交换产品系列
  • 保证产品之间的一致性

缺点

  • 扩展新产品困难(需要修改抽象工厂接口)
  • 增加了系统复杂度

实际应用场景

  1. 数据库访问层:为不同数据库(MySQL、Oracle、PostgreSQL)创建连接、查询等对象
  2. 跨平台应用:为不同操作系统创建文件系统、网络接口等
  3. 主题切换:为Web应用创建不同主题的UI组件
  4. 支付系统:为不同支付渠道(支付宝、微信、银联)创建支付、退款、查询对象

通过这个案例,你应该能理解抽象工厂模式的核心思想:提供一个创建一族相关对象的接口,而无需指定具体实现类。

抱歉,评论功能暂时关闭!