單例模式
PHP設計模式之一,單例模式,顧名思義就是只有一個實例。單例模式確保某一個類只有一個實例,不能重復實例,只能它自己實例化,而且向整個系統提供這個實例。
單例模式:即一個類只被實例化一次,當其他人對其再次實例化時,返回第一次實例化的對象,可以避免大量的new 操作,減少資源的消耗,典型應用於數據庫類的實例化
特點
三私一公
- 私有化靜態屬性
- 私有化構造方法
- 私有化克隆方法
- 公有化靜態方法
以實例化一個Mysql數據庫類為例:
要實現一個類只實例化一次,就必須堵住其他實例化的入口。
- 實例化類時,會自動調用類的構造方法,因為將構造方法設置為private屬性,限制為只能在類內部實例化
//私有構造方法,防止在類的外部實例化
private function __construct() {
# code...
}
- 定義一個靜態方法,在類內部實例化對象。實例化前先判斷該類是否已被實例化了,若已被實例化,就返回該實例化對象;若沒被實例化,便實例化一個對象並將該對象保存在類的靜態屬性中
//私有靜態屬性,存放該類的實例
private static $instance = null;
//公共的靜態方法,實例化該類本身,只實例化一次
public static function getInstance() {
if (!self::$instance instanceof self) {
self::$instance = new self;
}
return self::$instance;
}
- 禁止克隆,對象之間進行克隆可生成不同的對象。而克隆時會自動調用類的__conle方法,因此將克隆方法設置為private屬性
//私有克隆方法,防止克隆
private function __clone(){
# code...
}
綜上,三私一公(三個私有屬性和一個公共方法)單例模式的代碼如下:
class DB
{
private static $instance = null; //私有靜態屬性,存放該類的實例
private function __construct() //私有構造方法,防止在類的外部實例化
{
# code...
}
private function __clone() //私有克隆方法,防止克隆
{
# code
}
public static function getInstance() //公共的靜態方法,實例化該類本身,只實例化一次
{
if (!self::$instance instanceof self) {
self::$instance = new self;
}
return self::$instance;
}
}
代碼
<?php
namespace Brady\Design;
// 單例模式 三私一公
class Singleton
{
// 私有屬性 保存實例
private static $instance;
// 私有化構造方法 防止外界創建實例
private function __construct()
{
}
// 私有化克隆方法,防止外界克隆
private function __clone()
{
}
// 公有化方法 獲取實例
public static function getInstance()
{
if(!self::$instance instanceof self){
self::$instance = new self;
}
return self::$instance;
}
// 單例里面可以有其他方法 可以調用成功
public function query()
{
echo "query";
}
}
測試
實例化對象報錯
<?php
require "/phpwww/tools/vendor/autoload.php";
use Brady\Design\Singleton;
$instance = Singleton::getInstance();
$instance1 = Singleton::getInstance();
$instance2 = Singleton::getInstance();
var_dump($instance);
var_dump($instance1);
var_dump($instance2);
var_dump($instance===$instance1);
$instance2->query();
結果
➜ tools php test/design.php
object(Brady\Design\Singleton)#3 (0) {
}
object(Brady\Design\Singleton)#3 (0) {
}
object(Brady\Design\Singleton)#3 (0) {
}
bool(true)
➜ tools
可以看出得到的對象完全一致
推薦教程: