PHP 设计模式系列 —— 单例模式(Singleton)

1、模式定义

简单说来,单例模式的作用就是保证在整个应用程序的生命周期中,任何一个时刻,单例类的实例都只存在一个,同时这个类还必须提供一个访问该类的全局访问点。

常见使用实例:数据库连接器;日志记录器(如果有多种用途使用多例模式);锁定文件。

2、UML类图

单例模式类图

3、示例代码

Singleton.php

<?php

namespace DesignPatterns\Creational\Singleton;

/**
 * Singleton类
 */
class Singleton
{
    /**
     * @var Singleton reference to singleton instance
     */
    private static $instance;
    
    /**
     * 通过延迟加载(用到时才加载)获取实例
     *
     * @return self
     */
    public static function getInstance()
    {
        if (null === static::$instance) {
            static::$instance = new static;
        }

        return static::$instance;
    }

    /**
     * 构造函数私有,不允许在外部实例化
     *
     */
    private function __construct()
    {
    }

    /**
     * 防止对象实例被克隆
     *
     * @return void
     */
    private function __clone()
    {
    }

    /**
     * 防止被反序列化
     *
     * @return void
     */
    private function __wakeup()
    {
    }
}

4、测试代码

Tests/SingletonTest.php

<?php

namespace DesignPatterns\Creational\Singleton\Tests;

use DesignPatterns\Creational\Singleton\Singleton;

/**
 * SingletonTest用于测试单例模式
 */
class SingletonTest extends \PHPUnit_Framework_TestCase
{

    public function testUniqueness()
    {
        $firstCall = Singleton::getInstance();
        $this->assertInstanceOf('DesignPatterns\Creational\Singleton\Singleton', $firstCall);
        $secondCall = Singleton::getInstance();
        $this->assertSame($firstCall, $secondCall);
    }

    public function testNoConstructor()
    {
        $obj = Singleton::getInstance();

        $refl = new \ReflectionObject($obj);
        $meth = $refl->getMethod('__construct');
        $this->assertTrue($meth->isPrivate());
    }
}

学院君 has written 980 articles

Laravel学院院长,终身学习者

积分:112722 等级:P12 职业:手艺人 城市:杭州

11 条回复

  1. martion martion says:
    static::$instance = new static; 这里为什么是 new static,不是new Singleton 或者 new self 呢?
  2. chenchen chenchen says:
    /** * 通过延迟加载(用到时才加载)获取实例 * * @return self */ public static function getInstance() { if (null === static::$instance) { static::$instance = new static; } return static::$instance; } 这里将static 改成 self更好吧
  3. 11 11 says:
    __wakeup不能防止对象被反序列化啊.
  4. 你怎么又变黑了 你怎么又变黑了 says:
    @ 衣皇后 上午 测试了一下 代码 修改改一点 private 改成 protected
  5. 包小顺 包小顺 says:
    @ 李泊宁 要是有继承Singleton()这个类 static 就是 继承的那个类 不然就是Singleton()
  6. 你怎么又变黑了 你怎么又变黑了 says:
    if (null === static::$instance) { static::$instance = new static; } return static::$instance;static 是不是应该是Singleton()

登录后才能进行评论,立即登录?