只有一个实例,这是单例模式要解决的根本问题。
在PHP开发中有时候可能会对中一个类多次实例化,这会造成性能上的损失。 比如我们访问数据库时候肯定不会希望每次对数据库操作都去建立一个新的连接,因为这会造成系统资源的浪费。 那么如何让类只会有一个实例呢?我们知道通过new 类名可以创建实例, 所以必须禁止外部程序用new 类名的方式来创建多个实例,那么如何禁止呢?
我们只需将类的构造函数标记为private,那么类在外部就无法实例化了。
class A{
private function __construct(){}
}
通过将构造函数标记为私有化,该类已经不能通过new实例化了,那么我们如何访问类中的方法呢?
只需将类中的方法修饰为静态方法,那么我们就可以在外部调用了。
class A{
private function __construct(){}
public static function getInstance(){
echo '通过调用静态方法,获得实例对象';
}
}
A::getInstance(); //调用静态方法,类不需经过实例化。
现在我们已经可以访问到该类中的方法了,那么我们只需在类中实例化本身,并把实例的对象标识为静态变量,这样就可以保持该类实例的唯一性了。
class A{
private static $_instance=null; //类的实例
private function __construct(){}//魔术方法----构造方法
public static function getInstance(){
if (!(self::$_instance instanceof self)){ //判断类是否已经实例化
self::$_instance = new self();
}
return self::$_instance; //返回唯一实例
}
public function F(){
return 'A';
}
}
$A = A::getInstance();
echo $A->F(); //A
以上代码基本可以达到我们的需求,但是PHP语言是可以克隆对象的,为了防止对象被克隆从而破坏单一职责还需用将魔术方法__clone()标识为private,防止被clone。
<?php
/*
*可以这样克隆,直接使用关键字clone 对象引用;
*/
$obj = new demo();
$copy = clone $obj;
?>
最终的单例如下:加上私有化的克隆方法
class A{
private static $_instance; //类的实例
private function __construct(){}
public static function getInstance(){
if (!(self::$_instance instanceof self)){ //判断类是否已经实例化
self::$_instance = new self();
}
return self::$_instance; //返回唯一实例
}
private function __clone(){}
public function F(){
return 'A';
}
}