快速搞定php單例模式

2021-08-01 16:01:43 字數 2928 閱讀 7012

單例模式,正如其名,允許我們建立乙個而且只能建立乙個物件的類。

這在整個系統的協同工作中非常有用,特別明確了只需乙個類物件的時候。

那麼,為什麼要實現這麼奇怪的類,只例項化一次?

在很多場景下會用到,如:配置類、session類、database類、cache類、file類等等。

這些只需要例項化一次,就可以在應用全域性中使用。

本文我們以資料庫類為例。

1 問題

如果沒有使用單例模式,會有什麼樣的問題?

如下是乙個簡單的資料庫連線類,它沒有使用單例模式。

class database }

然後建立3個物件:

$config = array(  

'db_name' => 'test',  

'db_host' => 'localhost',  

'db_user' => 'root',  

'db_pass' => 'root'); $db1 = new database($config); var_dump($db1); $db2 = new database($config); var_dump($db2); $db3 = new database($config); var_dump($db3);

這種情況下,每當我們建立乙個這個類的例項,就會新增乙個到資料庫的連線。

開發者每在乙個地方例項化一次這個類,就會在那裡多乙個資料庫連線。

不知不覺中,開發者就犯了個錯誤,給資料庫和伺服器效能帶來巨大的影響。

上面的**輸入如下:

object(database)[1]  public 'db' => object(pdo)[2]object(database)[3]  public 'db' => object(pdo)[4]object(database)[5]  public 'db' => object(pdo)[6]

每個物件都分配乙個新的資源id,都是新的引用,它們占用3個的記憶體空間。

如果有100個物件建立,就會占用記憶體中100塊不同的空間,而其餘99塊並非是必須的。

2 解決

開發者怎樣使用基礎框架,如何資料庫連線,這很難控制。

如果在**評審階段再找出問題,又會浪費大量的人力物力。

要解決這樣的問題,我們可以控制住基類,在源頭上限制這個類,使其無法生成多個物件,如果已經生成過,直接返回。

於是,我們的目標就是,控制資料庫類,使其生成一次而且只能生成一次物件。

如下就是單例模式連線資料庫**:

class database  

// 這是獲取當前類物件的唯一方式  

public static function getinstance($config = array())  

return self::$instance;  

}  // 獲取資料庫控制代碼方法  

public function db()  

// 宣告成私有方法,禁止轉殖物件  

private function __clone(){}  

// 宣告成私有方法,禁止重建物件  

private function __wakeup(){} }

再通過getinstance()方法使用類物件,

$config = array(  

'db_name' => 'test',  

'db_host' => 'localhost',  

'db_user' => 'root',  

'db_pass' => 'root'); $db1 = database::getinstance($config); var_dump($db1); $db2 = database::getinstance($config); var_dump($db2); $db3 = database::getinstance($config); var_dump($db3);

輸出資訊如下:

object(database)[1]  private 'db' => object(pdo)[2]object(database)[1]  private 'db' => object(pdo)[2]object(database)[1]  private 'db' => object(pdo)[2]

對比兩個輸出可以看出,單例模式中,不同物件獲得的資源id是一樣的。

也就是說,雖然我們用getinstance()獲取database類物件3次,其實引用的是乙個記憶體空間,pdo也只連線了資料庫一次。

以上的例子是資料庫連線類,要使用資料庫,在應用這樣獲得連線控制代碼:

$db = database::getinstance($config)->db();

如果是其他類,則按需要修改資料庫相關的**,單例實現部分保留。

3 特點

單例模式的特點是4私1公:乙個私有靜態屬性,構造方法私有,轉殖方法私有,重建方法私有,乙個公共靜態方法。

其他方法根據需要增加。

最基礎的單例模式**如下:

class singleton  

return self::$instance;  

}  private function __construct(){}  

private function __clone(){}  

private function __wakeup(){} }

$instance用以儲存類的例項化,getinstance()方法提供給外部本類的例項化物件:

對應的uml圖如下,

單例模式在應用請求的整個生命週期中都有效,這點類似全域性變數,會降低程式的可測試性。

大部分情況下,也可以用依賴注入來代替單例模式,避免在應用中引入不必要的耦合。

所以,對於僅需生成乙個物件的類,首先考慮用依賴注入方式,其次考慮用單例模式來實現。

標籤: 千鋒設計模式php

輕鬆搞定設計模式 單例模式

單例模式是一種物件建立型模式,使用單例模式可以保證為乙個類只生成唯一的例項物件。也就是說,在整個程式空間中,該類只存在乙個例項物件。在應用系統開發中如果有以下需求 因為單例模式可以保證為乙個類只生成唯一的例項物件,所以這些情況一般採用單例設計模式。單例模式分為餓漢式和懶漢式兩種。懶漢式 示例如下 c...

PHP單例模式

模式對於oop開發人員尤其有用,因為他有助於建立穩定的api,並且仍然保持一定的靈活度。一種模式可以幫助我們定義負責完成特定任務的物件,還可以允許我們全部修改掉某個類而不用修改與這些類打交道的 前者被稱為類的職責,後者被稱為類的多型性。單例模式被當作職責模式,他用來在應用程式中建立乙個單一的功能訪問...

php單例模式

單例模式 單例類 1 建構函式需要標記為private 訪問控制 防止外部 使用new操作符建立物件 單例類不能在其他類中例項化,只能被其自身例項化 2 擁有乙個儲存類的例項的靜態成員變數 3 擁有乙個訪問這個例項的公共的靜態方法 常用getinstance 方法進行例項化單例類,通過instanc...