WebjxCom提示:php教程:php设计模式介绍之单条模式.
静态方式
关于全局变量的问题
,甚至隐藏在getInstance()中的全局变量中也存在
。因为全局变量在脚本的任何地方都有效
,在没有注意到的情况下,你依然有可能破坏这个全局变量,
在getInstance()方法内部使用静态变量来存储Singleton是一个显得干净的办法
。第一个代码片断如下:
classDbConn{
//...
function&getInstance(){
static$instance=false;
if(!$instance)$instance=&newDbConn(M_E);
return$instance;
}
}
Zend1引擎在
PHP4中不能存储静态变量的引用(请看http://www.php.net/manual/en/language.variables.scope.php#AEN3609)。使用一个工作区存储静态数组,并且将这个单件实例的引用放置到一个已知的数组中。getInstance()方法如下:
classDbConn{
functionDbConn($fromGetInstance=false){
if(M_E!=$fromGetInstance){
trigger_error(‘TheDbConnclassisaSingleton,’
.’pleasedonotinstantiatedirectly.’);
}
}
function&getInstance(){
static$instance=array();
if(!$instance)$instance0=&newDbConn(M_E);
return$instance0;
}
}
这段代码很简单的选择了这个静态数组$instancede的第一个元素,用来保持单件DbConns实例的引用。
虽然这段代码有点依赖
PHP的布尔方式,但它比那个全局版本更严谨:在条件检测时,使用一个空的数组会得到结果false。就像在DbConn类的前一个版本一样,在函数的定义和赋值部分需要引用操作符。
PHP5中的单件模式
PHP5中更容易实现单件模式,PHP5对于类内部变量和函数的访问控制被加强了。将DbConn::_construct()构造方法设置为私有(private),这个类就不能被直接实例化。用UML图表示,PHP5的DbConn单件模式如下:
组合使用静态方法和静态变量保持这个实例,并且设置构造函数为私有,以防止直接实例化类而创建实例,代码如下:
classDbConn{
/**
*staticpropertytoholdsingletoninstance
*/
static$instance=false;
/**
*constructor
*privatesoonlygetInstance()methodcaninstantiate
*@returnvoid
*/
privatefunction__construct(){}
/**
*factorymethodtoreturnthesingletoninstance
*@returnDbConn
*/
publicfunctiongetInstance(){
if(!DbConn::$instance){
DbConn::$instance=newDbConn;
}
returnDbConn::$instance;
}
}