定义
一个类有且仅有一个实例,并且自行实例化后提供给整个程序使用。
或者可以理解为在整个程序运行期间,保证这个类有且仅一个实例,并对外提供一个能够访问它的全局访问点。
应用场景
单例模式是一种常见的设计模式,在计算机系统中,线程池、缓存、日志对象、对话框、打印机、数据库操作、显卡的驱动程序常被设计成单例。
实现方法
单例模式的三个要点:
(1). 需要一个保存类的唯一实例的静态成员变量:
/**
* 自身实例
*
* @var object
*/
private static $_instance;
(2). 构造函数和克隆函数必须声明为私有的,防止外部程序new类从而失去单例模式的意义:
/**
* 构造函数
*
* @return void
*/
private function __construct()
{
}
/**
* 魔法方法
* 禁止clone对象
*
* @return string
*/
public function __clone()
{
echo 'clone is forbidden';
}
(3). 必须提供一个访问这个实例的公共的静态方法(通常为getInstance方法),从而返回唯一实例的一个引用
/**
* 获取实例
*
* @return object
*/
public static function getInstance()
{
if (!self::$_instance instanceof self) {
self::$_instance = new self;
}
return self::$_instance;
}
完整示例
/**
* 单例
*/
class Singleton
{
/**
* 自身实例
*
* @var object
*/
private static $_instance;
/**
* 构造函数
*
* @return void
*/
private function __construct()
{
}
/**
* 魔法方法
* 禁止clone对象
*
* @return string
*/
public function __clone()
{
echo 'clone is forbidden';
}
/**
* 获取实例
*
* @return object
*/
public static function getInstance()
{
if (!self::$_instance instanceof self) {
self::$_instance = new self;
}
return self::$_instance;
}
/**
* 测试方法
*
* @return string
*/
public function test()
{
echo "这是个测试 \n";
}
}
// 获取单例
$instance = Singleton::getInstance();
$instance->test();
// clone对象试试
$instanceClone = clone $instance;
单例模式优缺点
优点
提供了对唯一实例达到受控访问。
由于在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象单例模式无疑可以提高系统的性能。
缺点
单例模式破坏了常见的类模式以及没有抽象层,因扩展时有很大的困难。
单例模式为了能够保持运行期间唯一并能够被全局访问,污染了全局变量。
PHP缺点:
PHP语言是一种解释型的脚本语言,这种运行机制使得每个PHP页面被解释执行后,所有的相关资源都会被回收。也就是说,PHP在语言级别上没有办法让某个对象常驻内存,这和asp.net、Java等编译型是不同的,比如在Java中单例会一直存在于整个应用程序的生命周期里,变量是跨页面级的,真正可以做到这个实例在应用程序生命周期中的唯一性。然而在PHP中,所有的变量无论是全局变量还是类的静态成员,都是页面级的,每次页面被执行时,都会重新建立新的对象,都会在页面执行完毕后被清空,这样似乎PHP单例模式就没有什么意义了,所以PHP单例模式我觉得只是针对单次页面级请求时出现多个应用场景并需要共享同一对象资源时是非常有意义的。
总之,我认为单例模式有最重要的两点,保证唯一以及节省资源。
网友评论