当前位置: 首页 > article >正文

Java设计模式 二十六 工厂模式 + 单例模式

工厂模式 + 单例模式

工厂模式单例模式的组合是一种常见的设计模式组合,通常用于确保某些全局共享的资源(如配置管理器、数据库连接池等)只有一个实例,同时通过工厂方法提供统一的对象创建方式。


1. 场景说明

工厂模式用于创建对象,提供了一种灵活的对象实例化方式。单例模式用于确保某个类只有一个实例,并提供全局访问点。两者的结合通常应用于以下场景:

  • 数据库连接工厂: 确保数据库连接池只有一个工厂实例,同时提供连接对象的创建。
  • 配置管理器: 确保配置管理器类只有一个实例,通过工厂方法管理不同的配置对象。
  • 日志系统: 确保日志管理器只有一个实例,同时根据需要生成不同类型的日志记录器。

2. 模式组合的优点

  1. 唯一性: 单例模式保证工厂类的唯一性,避免了工厂类被多次实例化。
  2. 扩展性: 工厂模式为创建对象提供了灵活性,可以通过多态或其他扩展方式动态创建不同类型的对象。
  3. 全局访问: 单例模式提供了全局访问点,工厂模式集中管理对象的创建逻辑,二者结合使得系统结构清晰。

3. 实现示例:数据库连接工厂

以下示例展示了一个数据库连接工厂的实现,工厂类采用单例模式,确保只有一个工厂实例。


(1) 数据库连接类

数据库连接类表示单个连接对象。

// 数据库连接类
public class DatabaseConnection {
    private String connectionString;

    public DatabaseConnection(String connectionString) {
        this.connectionString = connectionString;
    }

    public void connect() {
        System.out.println("连接到数据库: " + connectionString);
    }
}

(2) 工厂类

工厂类使用单例模式,确保只有一个工厂实例,负责创建数据库连接对象。

// 工厂类
public class DatabaseConnectionFactory {
    // 单例实例
    private static DatabaseConnectionFactory instance;

    // 私有构造方法
    private DatabaseConnectionFactory() {}

    // 获取单例实例
    public static DatabaseConnectionFactory getInstance() {
        if (instance == null) {
            synchronized (DatabaseConnectionFactory.class) { // 线程安全的单例
                if (instance == null) {
                    instance = new DatabaseConnectionFactory();
                }
            }
        }
        return instance;
    }

    // 工厂方法:创建数据库连接
    public DatabaseConnection createConnection(String connectionString) {
        return new DatabaseConnection(connectionString);
    }
}

(3) 客户端代码

客户端代码通过单例工厂创建数据库连接对象。

public class Client {
    public static void main(String[] args) {
        // 获取工厂实例
        DatabaseConnectionFactory factory = DatabaseConnectionFactory.getInstance();

        // 创建数据库连接
        DatabaseConnection connection1 = factory.createConnection("jdbc:mysql://localhost:3306/db1");
        connection1.connect();

        DatabaseConnection connection2 = factory.createConnection("jdbc:postgresql://localhost:5432/db2");
        connection2.connect();

        // 确保工厂是单例
        DatabaseConnectionFactory anotherFactory = DatabaseConnectionFactory.getInstance();
        System.out.println(factory == anotherFactory); // 输出: true
    }
}

运行结果:
连接到数据库: jdbc:mysql://localhost:3306/db1
连接到数据库: jdbc:postgresql://localhost:5432/db2
true

4. 扩展示例:多类型对象的工厂

在某些场景下,工厂需要根据不同的参数创建不同类型的对象,工厂模式和单例模式的结合依然适用。例如:日志管理系统。


(1) 日志记录器接口
// 日志记录器接口
public interface Logger {
    void log(String message);
}

(2) 具体日志记录器
// 文件日志记录器
public class FileLogger implements Logger {
    @Override
    public void log(String message) {
        System.out.println("文件日志记录: " + message);
    }
}

// 控制台日志记录器
public class ConsoleLogger implements Logger {
    @Override
    public void log(String message) {
        System.out.println("控制台日志记录: " + message);
    }
}

(3) 单例工厂类
// 日志工厂类
public class LoggerFactory {
    private static LoggerFactory instance;

    private LoggerFactory() {}

    public static LoggerFactory getInstance() {
        if (instance == null) {
            synchronized (LoggerFactory.class) {
                if (instance == null) {
                    instance = new LoggerFactory();
                }
            }
        }
        return instance;
    }

    public Logger createLogger(String type) {
        if ("file".equalsIgnoreCase(type)) {
            return new FileLogger();
        } else if ("console".equalsIgnoreCase(type)) {
            return new ConsoleLogger();
        } else {
            throw new IllegalArgumentException("未知的日志类型: " + type);
        }
    }
}

(4) 客户端代码
public class Client {
    public static void main(String[] args) {
        LoggerFactory loggerFactory = LoggerFactory.getInstance();

        Logger fileLogger = loggerFactory.createLogger("file");
        fileLogger.log("这是文件日志");

        Logger consoleLogger = loggerFactory.createLogger("console");
        consoleLogger.log("这是控制台日志");
    }
}

运行结果:
文件日志记录: 这是文件日志
控制台日志记录: 这是控制台日志

5. 优缺点

优点:
  1. 全局唯一性: 单例模式确保工厂类唯一,全局共享。
  2. 灵活扩展: 工厂模式使得对象创建逻辑集中在工厂类中,新增对象类型时无需修改客户端代码。
  3. 高效管理: 工厂和单例结合能够高效管理系统中的全局资源,例如数据库连接、日志管理器等。
缺点:
  1. 复杂性增加: 模式组合会增加系统的复杂度,可能引入过度设计的问题。
  2. 线程安全性: 单例模式需要考虑多线程环境下的安全性,增加了实现的复杂性。

6. 总结

工厂模式 + 单例模式的组合是一种常见的设计模式组合,用于解决全局唯一资源的创建和管理问题。通过将工厂类设计为单例,我们可以确保全局共享的工厂实例,同时通过工厂模式灵活创建不同类型的对象。这种组合在实际开发中非常实用,特别是在需要集中管理全局资源(如数据库连接、日志系统、配置管理器)时尤为适合。


http://www.kler.cn/a/519433.html

相关文章:

  • 八股文 (一)
  • 引领产品创新: 2025 年 PM 效能倍增法则
  • 沃尔玛 礼品卡绑定 分析
  • 逐笔成交逐笔委托Level2高频数据下载和分析:20250124
  • Linux 系统服务开机自启动指导手册
  • Jetson nano 安装 PCL 指南
  • [ Spring ] Spring Cloud Alibaba Message Stream Binder for RocketMQ 2025
  • 我谈区域偏心率
  • 【Android】乱七八糟的小结
  • 健身房项目 Uniapp+若依Vue3版搭建!!
  • gtest with ros
  • Qwen2-VL:在任何分辨率下增强视觉语言模型对世界的感知 (大型视觉模型 核心技术 分享)
  • AutoMapper的使用
  • stm8s单片机(三)时钟系统与时钟切换
  • 【工具】CountUp.js
  • 国产编辑器EverEdit - 目录树
  • SSH代理實用指南
  • 【Matlab高端绘图SCI绘图模板】第003期 绘制面积填充图
  • 【AI非常道】二零二五年一月,AI非常道
  • 数据结构——概念与时间空间复杂度
  • 【Java】面试中遇到的两个排序
  • 策略模式 - 策略模式的使用
  • 【Leetcode刷题记录】18.四数之和
  • HTML5和CSS3拔高
  • mysql数据库启动出现Plugin ‘FEEDBACK‘ is disabled.问题解决记录
  • 08.OSPF 特殊区域及其他特性