单例模式:
单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
单例模式是一种常见的设计模式,在计算机系统中,线程池,缓存,日志对象,对话框,打印机,数据库操作,显卡的驱动常被设计成单例
单例模式分3种:懒汉式单例,饿汉式单例,登记式单例。
特点:
1.只能有一个实例
2.必须自行创建这个实例
3,必须给其他对象提供这一实例
场景:
PHP一个主要应用场景就是应用程序与数据库打交道的场景,在一个应用中会存在大量的数据库操作,针对数据库句柄连接数据库的行为,适用单例模式可以避免大量的new操作。因为每一次new操作都会消耗系统和内存的资源。
在没使用单例模式的情况下:
$db = new DB();
//比如有个应用场景是添加一条用户信息
$db->addUserInfo();
//然而我们需要早另外一个地方要使用这个用户信息,这时要用到数据库句柄资源,可能会这么做
function test(){
$db = new DB();
$db->getUserInfo();
}
PHP单例模式
上面的对象图中,有一个“单例对象”,而“客户甲”、“客户乙”和“客户丙”是单例对象的是那个客户对象。可以看到客户对象共享一个单例对象。而从单例对象到自身的连线可以看出,单例对象是有对自己的引用。
例:
class User {
//静态变量保存全局实例
private static $_instance = null;
private $name;
//私有构造函数,防止外界实例化对象
private function __construct() {
}
//私有克隆函数,防止外办克隆对象
private function __clone() {
}
//静态方法,单例统一访问入口
static public function getInstance() {
if (is_null ( self::$_instance ) || isset ( self::$_instance )) {
self::$_instance = new self ();
}
return self::$_instance;
}
public function getName() {
echo $this->name;
}
public function setName($name){
$this->name = $name;
}
}
$a = User::getInstance();
$a->setName('Jack Ma');
$b = User::getInstance();
$b->setName('Pony Ma');
echo $a->getName();//输出Pony Ma
echo $b->getName();//输出Pony Ma
只会实例化一个对象,对象$a和$b指向的是同一个实例化的User对象,通俗地说$a和$b都指向同一个内存地址。故而在$b对象在setName时,覆盖了$a对象设置的Jack Ma,最终$name = 'Pony Ma'。
优点:
省内存
缺点:
1,难调试
2,隐藏的依赖关系
3,无法用错误类型的数据复写一个单例