登录 注册

登录

问题 [原创/首发]joomla里面的单例模式和纯静态类

  • 影雪
  • 话题作者
  • 离线
  • COM_KUNENA_SAMPLEDATA_RANK2
  • COM_KUNENA_SAMPLEDATA_RANK2
  • 学海无涯苦作舟
更多
2009年12月11日 17:57 - 2009年12月11日 18:02 #1 作者: 影雪
[原创]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高级程序设计 模式、框架与测试)》,当当、卓越有售。

路漫漫而修远兮,吾将上下而求索 [本人开发的免费网赚程序  www.shadowsnow.cn/GetForFree/index.asp]

登录 或者   注册一个会员帐号 来参与讨论

更多
2009年12月11日 19:11 #2 作者: megakea
lz发的都是纯技术贴!厉害!顶!!!

登录 或者   注册一个会员帐号 来参与讨论