设计模式之抽象工厂模式

发布于:2025-07-01 ⋅ 阅读:(22) ⋅ 点赞:(0)

定义

      提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

结构

在这里插入图片描述

抽象工厂与工厂方法的对比说明

1)核心对比

维度 工厂方法模式 抽象工厂模式
产品结构 单一产品等级结构 多个产品等级结构
抽象产品数量 1个抽象产品接口/类 多个抽象产品接口/类
工厂职责 每个具体工厂只创建 1 种具体产品 每个具体工厂可创建多个相关产品(产品族)

2)扩展机制
      新增产品类型‌:
      工厂方法:需新增具体产品类 + 对应      工厂类(符合开闭原则);
      抽象工厂:需修改抽象工厂接口及所有实现类(违反开闭原则)。
      新增产品族‌:
      工厂方法:无法直接扩展产品族;
      抽象工厂:只需新增具体工厂类(符合开闭原则)。

适用场景

      适用于创建‌成套关联对象‌(如:跨平台 UI 组件家族)

使用示例

      这里以jdbc的简化版设计为例。
      定义抽象产品1

/**
 * 抽象产品1:连接
 */
public interface Connection {

    Statement createStatement();

    void close();

}

      定义抽象产品2

/**
 * 抽象产品2:语句
 */
public interface Statement {

    ResultSet executeQuery(String sql);

    void close();

}

      定义抽象产品3

/**
 * 抽象产品3:结果集
 */
public interface ResultSet {

    boolean next();

    String getString(int column);

    void close();

}

      定义抽象工厂

/**
 * 抽象工厂接口
 * 这里看似之定义创建了一个产品,其实是创建一组关联产品,只不过是通过层级创建的
 * 层级创建机制的本质
 *  Driver是根工厂‌:负责创建产品族的起点Connection
 *  Connection是子工厂‌:创建同系列的Statement
 *  Statement是末端工厂‌:创建配套的ResultSet
 *
 * 每个数据库驱动本质上定义了‌一整套不可分割的技术栈‌
 */
interface Driver {
    Connection connect(String url);
}

      以下是MySQL的实现示例

public class MySQLConnection implements Connection {

    public Statement createStatement() {
        return new MySQLStatement();
    }
    public void close() {
        System.out.println("MySQL连接关闭");
    }

}
public class MySQLStatement implements Statement {

    public ResultSet executeQuery(String sql) {
        System.out.println("执行MySQL查询: " + sql);
        return new MySQLResultSet();
    }

    public void close() {
        System.out.println("MySQL语句关闭");
    }

}

public class MySQLResultSet implements ResultSet {

    public boolean next() {
        return false;
    }

    public String getString(int column) {
        return "MySQL数据";
    }

    public void close() {
        System.out.println("MySQL结果集关闭");
    }

}
public class MySQLDriver implements Driver {

    public Connection connect(String url) {
        System.out.println("建立MySQL连接: " + url);
        return new MySQLConnection();
    }

}

      以下是Oralce实现示例

public class OracleConnection implements Connection {

    public Statement createStatement() {
        return new OracleStatement();
    }

    public void close() {
        System.out.println("Oracle连接关闭");
    }

}
public class OracleStatement implements Statement {

    public ResultSet executeQuery(String sql) {
        System.out.println("执行Oracle查询: " + sql);
        return new OracleResultSet();
    }

    public void close() {
        System.out.println("Oracle语句关闭");
    }

}
public class OracleResultSet implements ResultSet {

    public boolean next() {
        return false;
    }

    public String getString(int column) {
        return "Oracle数据";
    }

    public void close() {
        System.out.println("Oracle结果集关闭");
    }

}
public class OracleDriver implements Driver {

    public Connection connect(String url) {
        System.out.println("建立Oracle连接: " + url);
        return new OracleConnection();
    }

}

      测试


public class Client {

    public static void main(String[] args) {
        // 注册驱动
        Driver mysqlDriver = new MySQLDriver();

        // 使用MySQL产品族
        Connection mysqlConn = mysqlDriver.connect("jdbc:mysql://localhost:3306/db");
        Statement stmt = mysqlConn.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT * FROM users");
        System.out.println(rs.getString(1));

        // 关闭资源(实际应使用try-with-resources)
        rs.close();
        stmt.close();
        mysqlConn.close();
    }

}

springboot项目中关于工厂模式的一点理解

      工厂模式在 Spring Boot 项目中显式使用的频率较低,主要是因为 Spring 框架的核心机制(IoC 容器和依赖注入)已经内建并自动化了工厂模式的核心理念。

1)Spring 本身就是“超级工厂”‌

      1.1)IoC 容器作为工厂‌:Spring 的 ApplicationContext 本质上是一个‌高级工厂‌,负责创建、管理和装配对象(Bean)。开发者无需手动编写工厂类,Spring 已实现了工厂模式的全部流程。

      1.2)依赖注入替代工厂调用‌:传统工厂模式需要显式调用 Factory.createXxx() 获取对象,而在 Spring 中只需通过 @Autowired 或构造函数注入,由容器自动提供实例。

2) ‌Spring 提供了更灵活的依赖管理‌

      2.1)接口与实现解耦‌:通过 @Autowired 注入接口时,Spring 会自动找到其实现类(如 MyService 接口有 ServiceImplA 和 ServiceImplB 两个实现)。

      2.2)动态选择实现‌:结合 @Primary、@Qualifier 或配置文件(如 @Conditional),无需编写工厂代码即可动态切换实现。

3)Spring 原生支持工厂模式的变体‌

      即使需要复杂创建逻辑,Spring 也提供了更优雅的替代方案:

      3.1)@Bean 方法‌:在配置类中定义复杂对象的构建逻辑。

      3.2)FactoryBean 接口‌:专为复杂对象设计(如集成第三方库)。


网站公告

今日签到

点亮在社区的每一天
去签到