【设计模式】单件模式

引入

单件(Singleton)模式也是创建型模式的一种。单件模式和其它创建型模式很大的不同就是单件模式是限制而不是促进了类的创建。具体来说,单件模式确保了类有且只有一个实例,并且提供了一个对实例的全局访问点。

使用场景

不同的应用,不同的业务会有不同的场景,是否使用单件模式一方面需要从业务需求上考虑,一方面要从资源管理上考虑。从业务上考虑,最常见的比如Window 系统的任务管理器、回收站等等,他总是保证有且只有一个窗口,方便了使用者操作;从资源管理上考虑,比如访问数据库的线程池,它必须有且只能有一个,不然会出各种问题,比如对于一个公共的数据池,我们只需要维护一个实例,或许为了防止多线程操作,还需要加上读写锁。

示例代码

我们先写一个测试类Singleton,这个类有个私有的静态属性 instance ,用来指定唯一的实例,然后我们将构造方法设置为私有,同时提供一个公共静态方法 getInstance 用来创建、获取单实例:

<?php
 
/**
 * Created by PhpStorm.
 * User: AppDays
 * Date: 2017/4/26
 * Time: 21:04
 */
class Singleton
{
    /*
     * 私有静态变量,指定唯一实例
     */
    private static $instance;
    /*
     * 构造函数设为私有
     */
    private function __construct(){}
    /*
     * 实例创建时间,用来检测是否为同一个实例
     */
    private $create_time;
 
    /**
     * Desc: 获取单实例唯一入口
     * User: AppDays
     * Time: 2017-4-26 21:10:59
     * @return Singletom
     */
    public static function getInstance(){
        if(empty(self::$instance)){//如果变量为空,则实例化一个对象
            self::$instance = new Singleton();
            //实例创建时间
            self::$instance->create_time=time();
        }
        //返回单实例
        return self::$instance;
    }
 
    /*
     * 获取实例创建时间,测试单实例
     */
    public function getCreateTime(){
        return $this->create_time;
    }
 
}

如上代码,我们还写了一个私有属性 create_time,当第一次创建唯一实例时,我们将当前的时间戳赋值给这个属性,然后我们在不同的时间,获取对象,并访问 getCreateTime方法,如果两次的create_time 一致,则说明单例模式成功:

<?php
/**
 * Created by PhpStorm.
 * User: AppDays
 * Date: 2017/4/26
 * Time: 21:20
 */
include_once "Singleton.php";
/**
 * 获取单实例
 */
$instance = Singleton::getInstance();
/*
 * 打印实例创建时间
 */
echo $instance->getCreateTime();
echo '</br>';
/*
 * 阻塞线程3秒
 */
sleep(3);
/**
 * 重新获取实例
 */
$instance = Singleton::getInstance();
/*
 * 打印实例创建时间
 */
echo $instance->getCreateTime();

代码所示,两次请求中我间隔了3秒时间,运行结果如下图:

20170430173211

两次获取到的create_time值一致,即两次获取到的对象是同一个。

源码

github/appdays/DesignPattern