单例模式:
一个类最多只能创建出一个对象就叫单例模式。
1. 三私一公
三私一公是业内对单例模式的一句口诀。三私是指构造方法、克隆方法以及存储对象的静态属性私有化。
构造方法私有化是防止在外部重复实例化
克隆方法私有化目的是防止对象被克隆从而造成多个对象的现象
静态属性私有化是防止被外部更改其值,导致对象重新示例化,具体的可以看看下面的单例代码的 getInstance 静态方法
//单例模式,一个类只能创建一个对象
class Single
{
//定义一个静态私有的属性来保存对象
private static $single;
//私有化构造方法,禁止从外部实例化当前类
private function __construct($param)
{
//此处只会执行一次
var_dump($param);
}
//私有化克隆方法,防止他人复制当前对象
private function __clone(){}
//开放一个入口,用于获取当前类的对象
public static function getInstance($param)
{
// 判断当前类是否已经实例化
// 没有则实例化,否则直接返回上次实例化的对象
if(!self::$single){
self::$single = new static($param);
}
return self::$single;
}
}
在上面的getInstance中我们使用 new static 来实例化对象,这种方式没有任何问题。如果我们使用 new self 来实例化,现在有一个A_object类继承 Single 类,A_object中定义一个自定义方法,实例化A_object后无法调用自定义方法。具体代码如下所示:
class A_object extends Single{
function test_self(){
var_dump('test_self');
}
}
$a = A_object::getInstance(null);
//如果getInstance使用new self方式实例化,会直接报错
$a->test_self();
为什么使用 new self 会报错,错误信息表示test_self方法找不到。这就是self与static的主要区别即指向不同
self 指的是当前类,如果子类继承某个单例时,无法使用子类的属性及子类的方法
static 会指向最终类,如果有子类继承,在外部实例化,实际实例化出来的是最终子类
领取专属 10元无门槛券
私享最新 技术干货