首頁 >後端開發 >php教程 >API開發第三篇:PHP的設計模式完美的單例模式

API開發第三篇:PHP的設計模式完美的單例模式

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB原創
2016-08-08 09:30:00991瀏覽

今天來說一說單例模式。

        由於我以前是做java開發的,在使用單例模式的時候,首先想到的想用餓漢式,然後發現在PHP中,有這樣一個特性:因為PHP不支持在類別定義時給類別的成員變數賦予非基本型別的值。如表達式,new操作等等。所以了餓漢式這個就不行了。轉而想要確保這個單例模式的原子性,發現PHP中也沒有像JAVA中的線程安全問題。嘿嘿,你說PHP好不好?那OK接下來就試試PHP的懶漢式單例模式了。

先不說,我先上我第一個版本的單例模式代碼:

    // 定义私有静态变量.此种方式为:懒汉式单例(PHP中只有这种方式)
    private static $instance = null;
    // 私有化构成方法
    private function __construct(){
    }
    // 提供获取实例的公共方法
    public static function getInstance(){
        if(!(self::$instance instanceof self)){
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    // 私有__clone方法,禁止复制对象
    private function __clone(){

    }
OK,這段代碼看起很完美了,有註釋,有格式的,沒什麼問題了吧。但是當我在使用的過程中,我發現了一下問題

我的A類是單例模式的,然後我的B類繼承自A類,然後我調用如下方法:

$a = A::getInstance();
$b = B::getInstance();
var_dump($a === $b);
輸出的結果是:bool(true)
這個輸出結果是什麼意思呢?也就是說:B繼承自A後,我本來是B也變成單例模式,那麼A、B只是繼承管理,他們的物件不應該相等,而現在兩個的物件完全一樣了,只能說明:透過
$b = B::getInstance();
得到的對象,還是A類的對象,那這是怎麼回事?

問題出在self上,self的引用是在類別被定義時就決定的,也就是說,繼承了B的A,他的self引用仍然指向A。為了解決這個問題,在PHP 5.3中引入了後期靜態綁定的特性。簡單說是透過static關鍵字來存取靜態的方法或變量,與self不同,static的引用是由執行時間決定。於是簡單改寫一下我們的程式碼,讓單例模式可以重複使用。

class C
{
    protected static $_instance = null;
    protected function __construct(){
    }
    protected function __clone(){
    }
    public function getInstance(){
        if (static::$_instance === null) {
            static::$_instance = new static;
        }
        return static::$_instance;
    } 
}
class D extends C{
    protected static $_instance = null;
}
$c = C::getInstance();
$d = D::getInstance();
var_dump($c === $d);
這是時候的輸出就會變成:bool(false)

然後可以達到,只要繼承這個單例模式,那麼它的子類也是單例模式。就可以達到完美復用的作用,不用每次需要單例模式都去寫那麼多重複程式碼了。 注意上面的方法只有在PHP 5.3才能使用,對於先前版本的PHP,還是老實為每個單例類別寫一個getInstance()方法吧。

以上就介紹了API開發第三篇:PHP的設計模式完美的單例模式,包含了面向的內容,希望對PHP教學有興趣的朋友有幫助。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn