首页 >php教程 >php手册 >再谈PHP单例模式Singleton

再谈PHP单例模式Singleton

WBOY
WBOY原创
2016-06-13 09:39:011138浏览

单例模式属于创建型模式,它是设计模式中最简单的一种模式,当然它的使用也是无处不在的。

单例模式保证一个类仅有一个实例,并提供一个访问它的全局访问点。

当需要控制一个类的实例数量,且调用者可以从一个公共的众所周知的访问点访问时,我们就可以考虑使用单例模式了。

我们用 UML 来设计单例模式,当然在以后的设计模式的设计部分,我们都将采用 UML 来描述我们的设计,这样就更为形象化了。

从 UML 设计图中我们可以看出,为了让一个类只有一个实例,它必须创建一个静态变量,然后我们用一个公共静态的 Instance() 的方法来创建它,但是为了避免这个类自身的构造函数可以创建对象,我们将构造函数设置成 protected 或者 private,这样外部就只能通过 Instance() 的方法来创建一个静态的 Singleton 类。看来这样我们达到了我们的目的,接下来我们看代码:

public class Singleton  {
    private static Singleton instance;
    protected Singleton()
    public static Singleton Instance() {
        if(instance != null) instance = new Singleton();
        return instance;
    }
}

由此看来,实现单例模式我们可以做下列几步:

  1. 在类中创建一个静态变量,变量类型为当前类;
  2. 在类中创建一个公共的静态方法,让用户可以通过此方法创建此类的静态对象;
  3. 最后将构造函数设置为 protected 或者 private。

Program List:最简单的单例类

<?php
class Fruit
{
    static private $_color;
    private function __construct()
    {
    }
	
    static public function singleton() {
        return isset(self::$_color) ? self::$_color : self::$_color = new self();
    }
}
?>

Program List:可扩展的单例类

一个可扩展的单例类看似不可能,但下面的程序很接近这种效果。

    
<?php
class Test extends Fruit {
    public static function getInstance()
	{
        return Fruit::getSingleton(get_class());
    }
}
?>
<?php
class Fruit {
    /***********************
     * HOW TO USE
     * 
     * Inherit(extend) from Singleton and add getter:
     * 
     *  //public getter for singleton instance
     *     public static function getInstance(){
     *        return Singleton::getSingleton(get_class());
     *    }
     * 
     */
    
    private static $instanceMap = array();
    //protected getter for singleton instances
    protected static function getSingleton($className)
	{
        if(!isset(self::$instanceMap[$className]))
		{
            
       		$object = new $className;
            //Make sure this object inherit from Singleton
            if($object instanceof Fruit)
			{    
                self::$instanceMap[$className] = $object;
            }
            else
			{
                throw SingletonException("Class '$className' do not inherit from Singleton!");
            }
        }
        return self::$instanceMap[$className];
    }    
    
    //protected constructor to prevent outside instantiation
    protected function __construct(){
    }
    
    //denie cloning of singleton objects
    public final function __clone(){
        trigger_error('It is impossible to clone singleton', E_USER_ERROR);
    }    
}
?>
<?php
class Apple extends Fruit {
    
    protected $rndId;
    
    protected function __construct(){
        $this->rndId = rand();
    }    
    
    public function whatAmI(){
        echo 'I am a Apple('.$this->rndId.')<br />';
    }
    public static function getInstance(){
        return Fruit::getSingleton(get_class());
    }
}
class GreenApple extends Apple {
    public function whatAmI(){
        echo 'I am a GreenApple('.$this->rndId.')<br />';
    }
    
    public static function getInstance(){
        return Fruit::getSingleton(get_class());
    }
}
$apple1 = Apple::getInstance();
$apple2 = GreenApple::getInstance();
$apple1->whatAmI();// should echo 'I am a A(some number)
$apple2->whatAmI();// should echo 'I am a B(some number)
$apple1 = Apple::getInstance();
$apple2 = GreenApple::getInstance();
$apple1->whatAmI();// should echo 'I am a A(same number as above)
$apple2->whatAmI();// should echo 'I am a B(same number as above)
// $a = new A();// this should fail
// $b = new B();// this should fail
?>

程序运行结果:

I am a Apple(4462)
I am a GreenApple(8207)
I am a Apple(4462)
I am a GreenApple(8207)

Program List:单例类与其派生类

  
<?php
class Fruit
{
  // Hold an instance of the class
  private static $instance;
 
  // A private constructor; prevents direct creation of object
  protected function __construct()
  {
      echo 'I am constructed';
  }
  // The singleton method
  public static function singleton($classname = __CLASS__)
  {
      if (!isset(self::$instance)) {
          self::$instance = new $classname;
      }
      return self::$instance;
  }
}
class Apple extends Fruit {
   public static function singleton()
   {
       return parent::singleton(__CLASS__); // NOTE The singleton method MUST return an instance.
   }
   public function showColor()
   {
       echo 'My Color is Red.';
   }
}
$subclassInstance = Apple::singleton();
$subclassInstance->showColor();
?>

程序运行结果:

I am constructed
My Color is Red.
声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn