先來看一個最簡單的單例模式的實現:
運行結果如下:
但是光是這樣寫嚴格意義上來講並不是真正的單例模式,因為用戶完全可以通過new關鍵詞來實例化新的對象。
$test1 = new Singleton(); $test2 = new Singleton();運行結果如下:
所以我們要對我們的代碼做一點改進,將構造方法的訪問級別設置為protected:
這時當用戶試圖以new關鍵詞實例化一個新的對象時,會報如下截圖所示的錯誤:
當然,狡猾的用戶還是可以通過clone關鍵詞來克隆一個新對象:
$test1 = Singleton::getInstance(); $test2 = clone $test1; if($test1 === $test2){ echo 是同一個對象; }else{ echo 不是同一個對象; }
所以我們還要把__clone方法聲明為protected:
時當用戶試圖以clone關鍵詞克隆一個新的對象時,會報如下截圖所示的錯誤:
所以要嚴格意義上實現一個單例模式,要注意的有以下幾點:
1、將構造函數聲明為protected;
2、創建一個getInstance的靜態方法來獲取保存該類的靜態變量;
3、將__clone方法聲明為protected
當然在實際的開發中,大部分情況下只要實現簡單的單例模式就行了(第一個例子的寫法)。