//注:单例模式常用也常考,请认真练习
单例模式:
主要思路
1.保护或私有构造函数,防止外部实例化
2.内部开放一个公共的静态方法,负责实例化
3.类有一个静态属性存放对象
当静态属性已经存放对象,直接return 该对象。
第一步:一个普通的类
这个普通类,可以new来实例化
这显然不是单例
class single{
}
$s1=new single();
$s2=new single();
$s3=new single();
第二步:看来new是罪恶之源,干脆不让new了
我们把构造方法 保护/私有
外部不能new了
new了报错了
----但引入一个问题,不能new,那得不到对象,这不是单例,这是0例模式。
class single{
protected function
__construct(){
}
}
$s1=new single();
第三步,通过内部的static方法,来调用
class single{
public $hash; //证明
protected function __construct(){
$this->hash=mt_rand(1,99999);
//随机码 证明
}
static public function getInstance(){
return new
self();
//self 代表本类 也可以直接写上类名
}
}
$s1=single::getInstance();
$s2=single::getInstance();
两个对象什么时间相等?
答:只有指向一个对象地址的时候,才相等。
证明给你看!
打了证明的都是可以证明不是一个对象的
print_r($s1); //证明
print_r($s2); //证明
if($s1==$s2){
//证明
echo
'是一个对象';
//证明
}else{
echo
'不是一个对象';
//证明
}
//输出 不是一个对象
第四步,通过内部的static方法实例化,
并且,把实例保存在内部的静态属性上
简单的单例模式完成
class single{
public $hash;
static protected $ins=NULL;
protected function __construct(){
$this->hash=mt_rand(1,99999);
}
static public function getInstance(){
if(self::$ins instanceof self){ //instanceof
专门判断某个对象是不是某个类的实例用的
return self::$ins;
}
self::$ins=new self();
return self::$ins;
}
}
$s1=single::getInstance();
$s2=single::getInstance();
print_r($s1);
print_r($s2);
if($s1==$s2){
echo
'是一个对象';
}else{
echo
'不是一个对象';
}
//输出
是一个对象
//-----------------看问题------------------------//
class test extends single{
public
function __construct(){
parent::__construct();
}
}
$t1=new
test();
//假如 你改成
$t1=test::getInstance(); 那就没问题了
$t2=new test();
print_r($t1);
print_r($t2);
if($t1==$t2){
echo
'是一个对象';
}else{
echo
'不是一个对象';
}
//输出
不是一个对象
//问题1:我们辛苦写的单例,继承一下就不灵了
//解决 final 可以解决
class s{
public $hash;
static protected $ins=NULL;
final protected function
__construct(){
$this->hash=mt_rand(1,99999);
}
static public function getInstance(){
if(self::$ins instanceof self){ //instanceof
专门判断某个对象是不是某个类的实例用的
return self::$ins;
}
self::$ins=new self();
return self::$ins;
}
}
class t extends s{
}
$t1=t::getInstance();
$t2=t::getInstance();
print_r($t1);
print_r($t2);
$t3=clone
$t2;
//这里是克隆一份给$t3
if($t1===$t2){
echo
'是一个对象';
// 输出 是一个对象
}else{
echo
'不是一个对象';
}
echo "
";
if($t3===$t2){
//用全等于
暴露出不是一个对象
echo
'是一个对象';
}else{
echo
'不是一个对象';
// 输出 不是一个对象
}
t1 t2显然是一个对象
而clone出来的t3显然是另一个对象
//clone又多出一个对象,试问,如何解决?
//提示:请看魔术方法 clone
//魔术方法很多
__construct
__destruct
__clone
__callstatic
等等