[原创]joomla里面的单例模式和纯静态类 (作者: 影雪, 邮箱:
这个 E-mail 受反垃圾邮件程序保护,您需要启用 JavaScript 才能查看。)
单例模式顾名思义,就是只有一个实例。
作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。
单例模式的要点有三;
一是某个类只能有一个实例;
二是它必须自行创建这个实例;
三是它必须自行向整个系统提供这个实例。
在Joomla!涉及到了很多的单例模式,比如JFactory,JURI等等。
对于一个请求中需要一个对象实例的,joomla大多采用了单例模式,可以避免重复实例化带来的资源浪费和性能损耗。
请看下面这个严格的遵循了单例模式的类Singleton
<?php
//单例模式的定义:
class Singleton
{
private static $instance; // 1. 必须要有一个保存类的实例化的静态(static)成员变量,如 $instance,最好是私有化(private)的.
private function __construct(){} //2. 必须有一个构造函数__construct(),并且必须被标记为 私有化(private) .
private function __clone(){} //3. 最好创建一个空的,私有化(private) 的__clone()方法,防止对象被复制或者克隆.
public static function getInstance(){ //4. 拥有一个访问这个实例的公共的 (public) 静态 (static)方法
if( self::$instance instanceof self ) //5. 静态(static)方法里面不能用$this->var的形式,必须用作用域限定符::的形式(self::$var),其中self(代表子类)可以用parent(代表父类),static(PHP 6 新增),或者类名(如类Singleton)代替.
//6. instanceof操作符是一个比较操作符,接受左右两边的参数,并返回一个布尔值,确定对象的某个实例是否为特定的类型,或者是否从某个类型继承,或者是否实现了某个接口,或者是否某个类的实例
//7. self::$instance instanceof self 可用 !is_object($instance) 或者 self::$instance == null 等代替,但不太规范,不推荐使用.
{
self::$instance = new Singleton(); //8. 若不是本类的实例,则实例化本类
}
return self::$instance; //9. 若是本类实例化,则返回 保存本类的实例化的静态成员变量$instance
}
}
//单例模式的调用:
$instance = Singleton::getInstance();
?>
严格意义上, joomla没有真正的使用单例模式,请看下面的JFactory类,摘自 /libraries/joomla/factory.php
<?php
class JFactory
{
//2. JFactory没有一个标记为private的构造函数__construct()
//3. JFactory没有一个空的,标记为private的__clone()方法
function &getApplication($id = null, $config = array(), $prefix='J') //4. 方法非static,public默认可省略
{
static $instance; //1. $instance非private, 而且不是JFactory类里面的全局变量,所以每次调用JFactory类时,必须用调用&getApplication()方法,这是因为JFactory类有很多方法都需要实例化,不能单独用全局变量下的$instance保存实例
if (!is_object($instance)) //7.这里$instance不一定就是JFactory类的实例, 建议用self::$instance instanceof self 更加规范安全可靠.
{
jimport( 'joomla.application.application' ); //10. 加载libraries/joomla/application/application.php
if (!$id) {
JError::raiseError(500, 'Application Instantiation Error'); //5. id默认为空, 显示500-内部服务器错误信息
}
$instance = JApplication::getInstance($id, $config, $prefix); //8. $instance是JApplication类的实例化
}
return $instance; //9.此处$instance是局部变量,无需加self::
}
}
?>
若某个类不需要__construct()方法,,那么这个类就不适合使用单例模式,这种情况下可以使用纯静态类,
与单例模式不同的是:
2. __construct()构造函数必须没有函数体且标记为private
1. 去掉private static $instance;
4. 去掉public static function getInstance()
如以下的类SomeClass就是一个纯静态类
<?php
class SomeClass
{
private function __construct(){}//2. 防止类被实例化
private function __clone(){} //3. 最好创建一个空的,私有化(private) 的__clone()方法,防止对象被复制或者克隆.
public static function SomeMethod()
{
//执行一些操作
}
}
?>
要了解PHP的一些高级应用,建议阅览《Pro PHP Patterns, Framework, Testing and More(PHP高级程序设计 模式、框架与测试)》,当当、卓越有售。