admin管理员组

文章数量:1037775

每天认识一种设计模式之单例模式

单例模式的定义

单例模式(Singleton Pattern)是确保一个类只有一个实例,并提供一个全局访问点的设计模式。它常用于管理共享资源(如数据库连接、配置管理、日志记录器等)。

PHP 单例模式实现示例

代码语言:php复制
class Singleton
{
    // 1. 私有静态变量保存唯一实例
    private static $instance = null;

    // 2. 私有构造函数防止外部 new 实例化
    private function __construct()
    {
        // 初始化代码(如数据库连接)
    }

    // 3. 禁止克隆对象
    private function __clone()
    {
        // 防止通过克隆创建新实例
    }

    // 4. 防止反序列化(PHP 7.4+)
    public function __wakeup()
    {
        throw new Exception("Cannot unserialize singleton");
    }

    // 5. 全局访问点
    public static function getInstance(): self
    {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    // 示例方法
    public function doSomething()
    {
        echo "Singleton is working!";
    }
}

使用示例

代码语言:php复制
// 获取单例实例
$instance1 = Singleton::getInstance();
$instance2 = Singleton::getInstance();

// 验证是否为同一实例
var_dump($instance1 === $instance2); // 输出 bool(true)

// 调用方法
$instance1->doSomething(); // 输出 "Singleton is working!"

关键点说明

  • 私有构造函数 禁止通过 new 关键字在类外部实例化对象。
  • 静态访问方法 通过静态方法 getInstance() 控制实例的唯一性。
  • 防止克隆和反序列化
    • __clone() 设为私有,防止通过克隆创建新对象。
    • __wakeup() 抛出异常防止反序列化破坏单例。
  • 线程安全(PHP特性) PHP的Web应用中,每个请求独立处理,无需额外处理线程安全。但在CLI多线程环境下需加锁。

适用场景

  • 数据库连接池
  • 配置管理器
  • 日志记录器
  • 缓存管理器

注意事项

  • 全局状态问题:单例的全局访问性可能导致代码耦合,测试困难。
  • 依赖注入替代:现代框架推荐通过依赖注入容器管理单例。
  • 过度使用风险:不是所有需要唯一实例的场景都适用单例,需根据实际需求评估。

每天认识一种设计模式之单例模式

单例模式的定义

单例模式(Singleton Pattern)是确保一个类只有一个实例,并提供一个全局访问点的设计模式。它常用于管理共享资源(如数据库连接、配置管理、日志记录器等)。

PHP 单例模式实现示例

代码语言:php复制
class Singleton
{
    // 1. 私有静态变量保存唯一实例
    private static $instance = null;

    // 2. 私有构造函数防止外部 new 实例化
    private function __construct()
    {
        // 初始化代码(如数据库连接)
    }

    // 3. 禁止克隆对象
    private function __clone()
    {
        // 防止通过克隆创建新实例
    }

    // 4. 防止反序列化(PHP 7.4+)
    public function __wakeup()
    {
        throw new Exception("Cannot unserialize singleton");
    }

    // 5. 全局访问点
    public static function getInstance(): self
    {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    // 示例方法
    public function doSomething()
    {
        echo "Singleton is working!";
    }
}

使用示例

代码语言:php复制
// 获取单例实例
$instance1 = Singleton::getInstance();
$instance2 = Singleton::getInstance();

// 验证是否为同一实例
var_dump($instance1 === $instance2); // 输出 bool(true)

// 调用方法
$instance1->doSomething(); // 输出 "Singleton is working!"

关键点说明

  • 私有构造函数 禁止通过 new 关键字在类外部实例化对象。
  • 静态访问方法 通过静态方法 getInstance() 控制实例的唯一性。
  • 防止克隆和反序列化
    • __clone() 设为私有,防止通过克隆创建新对象。
    • __wakeup() 抛出异常防止反序列化破坏单例。
  • 线程安全(PHP特性) PHP的Web应用中,每个请求独立处理,无需额外处理线程安全。但在CLI多线程环境下需加锁。

适用场景

  • 数据库连接池
  • 配置管理器
  • 日志记录器
  • 缓存管理器

注意事项

  • 全局状态问题:单例的全局访问性可能导致代码耦合,测试困难。
  • 依赖注入替代:现代框架推荐通过依赖注入容器管理单例。
  • 过度使用风险:不是所有需要唯一实例的场景都适用单例,需根据实际需求评估。

本文标签: 每天认识一种设计模式之单例模式