MENU

PHP《设计模式》- 单例模式

March 31, 2019 • php,设计模式阅读设置

目的:

在整个应用程序的生命周期内(脚本启动到结束),只能拿到单例类的一个对象实例。
比如数据库连接这样的,其他类可以共用一个数据库连接对象实例,不能每次都去new导致连接数递增

实现原理

私有化 __construct 构造函数防止外部调用创建多个实例
私有化 __clone 防止外部克隆
私有化 __wakeup 防止序列化
声明一个 getInstance() 静态方法返回自己的唯一实例

具体代码如下

class Singleton
{
    /**
    * @var Singleton
    */
    private static $instance;

    /**
    * 通过懒加载获得实例(在第一次使用的时候创建)
    */
    public static function getInstance(): Singleton
    {
        if (null === static::$instance) {
            static::$instance = new static();
        }

        return static::$instance;
    }

    /**
    * 不允许从外部调用以防止创建多个实例
    * 要使用单例,必须通过 Singleton::getInstance() 方法获取实例
    */
    private function __construct()
    {
    }

    /**
    * 防止实例被克隆(这会创建实例的副本)
    */
    private function __clone()
    {
    }

    /**
    * 防止反序列化(这将创建它的副本)
    */
    private function __wakeup()
    {
    }

}

测试

$singleton1 = Singleton::getInstance();
var_dump($singleton1);

$singleton2 = Singleton::getInstance();
var_dump($singleton2);

$singleton3 = new Singleton();
var_dump($singleton3);

测试结果

object(Singleton)#1 (0) {
}
object(Singleton)#1 (0) {
}

Fatal error: Uncaught Error: Call to private Singleton::__construct() from invalid context in /Users/simon/Code/php/DesignPatternsPHP/Singleton.php:53
Stack trace:
#0 {main}

可以看到$singleton1和$singleton2使用的是同一个对象,而$singleton3去实例化就会报错

Last Modified: March 31, 2020
Archives QR Code
QR Code for this page
Tipping QR Code