您当前的位置: 首页 > 学无止境 > 网站建设 网站首页网站建设
燕十八面向对象-单例模式
发布时间:2015-09-01 07:49:36编辑:雪饮阅读()
1、单例模式初探
<?php
header("Content-type:text/html;charset=utf-8;");
/*
单例模式:
在团队协同开发时有如下案例:
首先有一个公共类mysql类
a开发者在开发时需要new通过mysql类中new一个对象进行数据处理
b开发者也是同样
这样一来就会造成多次的数据库冗余资源连接
单例模式就是为了解决这个问题,即mysql类只允许有一个对象
*/
class single{
public $hash;
static protected $ins=null;
protected function __construct(){
/*
将构造方法给予保护或者私有权限(protected或private)这样以来
只能够在内部访问,无法通过外部来实例化对象
*/
$this->hash=mt_rand(1,99999);
}
static public function getinstance(){
if(self::$ins instanceof self){
/*判断当前ins属性是不是当前类的实例化对象*/
return self::$ins;
}
self::$ins=new self();
return self::$ins;
//即便可以使用该静态方法实现new一个对象的效果
//但每次调用该方法都要实例化一次
/*这样未免还是浪费资源,所以我们需要将其new的对象保存下来*/
}
}
$a=single::getinstance();
echo "<pre>";
print_r($a);
echo "</pre>";
echo "<br/>继承下就不灵了,继承这个类的子类中又可以new了。。。。。<br/><hr/>";
class test extends single{
public function __construct(){
parent::__construct();
}
}
$b=new test();
echo "<pre>";
print_r($b);
echo "</pre>";
?>
2、子类new新对象的解决
<?php
/*
为了解决单例模式在类被继承后的bug,所以需要限制当前类不允许被继承,而final修饰符则起了重大作用
final修饰符在php中意为“最终版”的意思,也就是说被该修饰符修饰了的类或者方法已经是固化的了,无法再次更改
final修饰符在php中仅能修饰类和方法,对于属性无法修饰,所以如下案例是无法运行的,原因只有一个,那就是final修饰
的类是无法被继承的。
*/
header("Content-type:text/html;charset=utf-8;");
final 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){
return self::$ins;
}
self::$ins=new self();
return self::$ins;
}
}
$a=single::getinstance();
echo "<pre>";
print_r($a);
echo "</pre>";
echo "<br/>如此以来便无法继承该类了<br/><hr/>";
class test extends single{
public function __construct(){
parent::__construct();
}
}
$b=new test();
echo "<pre>";
print_r($b);
echo "</pre>";
?>
3、单例模式的逻辑问题
如果不让继承类,那么类便没有扩展性可言。final类虽然不能继承,但final方法却是可以使用,而且final方法不允许重构,那么:
<?php
header("Content-type:text/html;charset=utf-8;");
/*类不被继承,那么就无法扩展*/
class single{
public $hash;
static protected $ins=null;
final protected function __construct(){
/*
final修饰该方法防止被重构,被修改,final已经是最终版
*/
$this->hash=mt_rand(1,99999);
}
static public function getinstance(){
if(self::$ins instanceof self){
return self::$ins;
}
self::$ins=new self();
return self::$ins;
}
}
$a=single::getinstance();
echo "<pre>";
print_r($a);
echo "</pre>";
echo "<br/>如此一来继承类也不能够new新对象了,同时也实现了类的扩展,只不过需要以子类名来访问属性或方法<br/><hr/>";
class test extends single{
}
$b=test::getinstance();
echo "<pre>";
print_r($b);
echo "</pre>";
$c=test::getinstance();
$d=clone $c;//克隆c对象
/*使用严格相等来判断对象到底是不是同一个对象*/
if($b===$c){
echo "<br/>变量b与变量c是同一个对象<br/>";
}
else{
echo "<br/>变量b与变量c不是同一个对象<br/>";
}
if($d===$c){
echo "<br/>变量d与变量c是同一个对象<br/>";
}
else{
echo "<br/>变量d与变量c不是同一个对象<br/>";
}
/*
由严格相等的结果可知虽然无法通过继承来实现new新对象,但使用克隆方法clone照样可以实现多个对象,这样仍然不是绝对的单例模式
解决方法:在魔术方法中寻找解救之法
*/
?>
关键字词:燕十八,单例模式,个人博客