單例模式Singleton概述

單例模式屬於建立型模式,它是設計模式中最簡單的一種模式,固然它的使用也是無處不在的。
單例模式保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。
當須要控制一個類的實例數量,且調用者能夠從一個公共的衆所周知的訪問點訪問時,咱們就能夠考慮使用單例模式了。
咱們用 UML 來設計單例模式,固然在之後的設計模式的設計部分,咱們都將採用 UML 來描述咱們的設計,這樣就更爲形象化了。
從 UML 設計圖中咱們能夠看出,爲了讓一個類只有一個實例,它必須建立一個靜態變量,而後咱們用一個公共靜態的 Instance() 的方法來建立它,可是爲了不這個類自身的構造函數能夠建立對象,咱們將構造函數設置成 protected 或者 private,這樣外部就只能經過 Instance() 的方法來建立一個靜態的 Singleton 類。看來這樣咱們達到了咱們的目的,接下來咱們看代碼:
1 public class Singleton  {
2     private static Singleton instance;
3     protected Singleton()
4     public static Singleton Instance() {
5         if(instance != null) instance = new Singleton();
6         return instance;
7     }
8 }
由此看來,實現單例模式咱們能夠作下列幾步:
  1. 在類中建立一個靜態變量,變量類型爲當前類;
  2. 在類中建立一個公共的靜態方法,讓用戶能夠經過此方法建立此類的靜態對象;
  3. 最後將構造函數設置爲 protected 或者 private。

Program List:最簡單的單例類

01 <?php
02 class Fruit
03 {
04     static private $_color;
05     private function __construct()
06     {
07     }
08       
09     static public function singleton() {
10         return isset(self::$_color) ? self::$_color : self::$_color = new self();
11     }
12 }
13 ?>

Program List:可擴展的單例類

一個可擴展的單例類看似不可能,但下面的程序很接近這種效果。
001       
002 <?php
003 class Test extends Fruit {
004   
005     public static function getInstance()
006     {
007         return Fruit::getSingleton(get_class());
008     }
009   
010 }
011 ?>
012   
013 <?php
014 class Fruit {
015   
016     /***********************
017      * HOW TO USE
018      
019      * Inherit(extend) from Singleton and add getter:
020      
021      *  //public getter for singleton instance
022      *     public static function getInstance(){
023      *        return Singleton::getSingleton(get_class());
024      *    }
025      
026      */
027       
028     private static $instanceMap = array();
029   
030     //protected getter for singleton instances
031     protected static function getSingleton($className)
032     {
033         if(!isset(self::$instanceMap[$className]))
034         {
035               
036             $object = new $className;
037             //Make sure this object inherit from Singleton
038             if($object instanceof Fruit)
039             {    
040                 self::$instanceMap[$className] = $object;
041             }
042             else
043             {
044                 throw SingletonException("Class '$className' do not inherit from Singleton!");
045             }
046         }
047         return self::$instanceMap[$className];
048     }    
049       
050     //protected constructor to prevent outside instantiation
051     protected function __construct(){
052     }
053       
054     //denie cloning of singleton objects
055     public final function __clone(){
056         trigger_error('It is impossible to clone singleton', E_USER_ERROR);
057     }    
058 }
059 ?>
060   
061 <?php
062 class Apple extends Fruit {
063       
064     protected $rndId;
065       
066     protected function __construct(){
067         $this->rndId = rand();
068     }    
069       
070     public function whatAmI(){
071         echo 'I am a Apple('.$this->rndId.')<br />';
072     }
073   
074     public static function getInstance(){
075         return Fruit::getSingleton(get_class());
076     }
077   
078 }
079   
080 class GreenApple extends Apple {
081   
082     public function whatAmI(){
083         echo 'I am a GreenApple('.$this->rndId.')<br />';
084     }
085       
086     public static function getInstance(){
087         return Fruit::getSingleton(get_class());
088     }
089   
090 }
091   
092 $apple1 = Apple::getInstance();
093 $apple2 = GreenApple::getInstance();
094   
095 $apple1->whatAmI();// should echo 'I am a A(some number)
096 $apple2->whatAmI();// should echo 'I am a B(some number)
097   
098 $apple1 = Apple::getInstance();
099 $apple2 = GreenApple::getInstance();
100   
101 $apple1->whatAmI();// should echo 'I am a A(same number as above)
102 $apple2->whatAmI();// should echo 'I am a B(same number as above)
103   
104 // $a = new A();// this should fail
105 // $b = new B();// this should fail
106   
107 ?>
程序運行結果:
1 I am a Apple(4462)
2 I am a GreenApple(8207)
3 I am a Apple(4462)
4 I am a GreenApple(8207)

Program List:單例類與其派生類

01     
02 <?php
03   
04 class Fruit
05 {
06   // Hold an instance of the class
07   private static $instance;
08    
09   // A private constructor; prevents direct creation of object
10   protected function __construct()
11   {
12       echo 'I am constructed';
13   }
14   // The singleton method
15   public static function singleton($classname = __CLASS__)
16   {
17       if (!isset(self::$instance)) {
18           self::$instance = new $classname;
19       }
20       return self::$instance;
21   }
22 }
23   
24 class Apple extends Fruit {
25    public static function singleton()
26    {
27        return parent::singleton(__CLASS__); // NOTE The singleton method MUST return an instance.
28    }
29    public function showColor()
30    {
31        echo 'My Color is Red.';
32    }
33 }
34   
35 $subclassInstance = Apple::singleton();
36 $subclassInstance->showColor();
37 ?>
程序運行結果:
1 I am constructed
2 My Color is Red.
相關文章
相關標籤/搜索