標籤:mysql 重要 應用 多少 運行 ext 作用 com name
參考:http://www.cnblogs.com/yangjinjin/archive/2013/01/31/2887492.html
李炎恢PHP第三季視頻
單例模式
單例模式確保某個類只有一個執行個體,而且自行執行個體化並向整個系統提供這個執行個體。
單例模式有以下3個特點:
1.只能有一個執行個體。
2.必須自行建立這個執行個體。
3.必須給其他對象提供這一執行個體。
PHP一個主要應用場合就是應用程式與資料庫打交道的情境,在一個應用中會存在大量的資料庫操作,針對資料庫控制代碼串連資料庫的行為,使用單例模式可以避免大量的new操作。因為每一次new操作都會消耗系統和記憶體的資源。
//初始化一個資料庫控制代碼$db = new DB(...);//比如有個應用情境是添加一條使用者資訊
$db->addUserInfo();....../
/然而我們要在另一地方使用這個使用者資訊,這時要用到資料庫控制代碼資源,可能會這麼做
......function test() {
$db = new DB(...);
$db->getUserInfo();......
有些朋友也許會說,可以直接使用global關鍵字!
global $db;
的確global可以解決問題,也起到單例模式的作用,但在OOP中,我們拒絕這種編碼。因為global存在安全隱患(全域變數不受保護的本質)。
全域變數是物件導向程式員遇到的引發BUG的主要原因之一。這是因為全域變數將類捆綁於特定的環境,破壞了封裝。如果新的應用程式無法保證一開始就定義了相同的全域變數,那麼一個依賴於全域變數的類就無法從一個應用程式中提取出來並應用到新應用程式中。
確切的講,單例模式恰恰是對全域變數的一種改進,避免那些儲存唯一執行個體的全域變數汙染命名空間。你無法用錯誤類型的資料覆寫一個單例。這種保護在不支援命名空間的PHP版本裡尤其重要。因為在PHP中命名衝突會在編譯時間被捕獲,並使指令碼停止運行。
以執行個體化資料庫連接為例:
<?php
class DB{
private $_db;
//靜態可以通過類直接存取,不需要new,private外部不能訪問
static private $_instance;
//訪問這個執行個體的公用靜態方法
static public function getInstance()
{
//如果對象沒有建立就建立並返回,如果已經建立過就直接返回
if (!(self::$_instance instanceof self)){
self::$_instance = new self();
}
return self::$_instance;
}
//單一職責問題,私人化clone
private function __clone(){}
private function __construct()
{
try{
$this->_db = new PDO(‘mysql:host=127.0.0.1;dbname=shop3‘,‘root‘,‘‘);
echo ‘建立了一次資料庫連接對象‘.‘<br/>‘;
}catch (PDOException $e){
exit($e->getMessage());
}
}
public function query($sql)
{
return $this->_db->query($sql);
}
}
首先是執行個體化對象的時候,調用構造方法,執行個體化一個PDO對象,建立起資料庫連接,將控制代碼賦值給私人屬性$_db。但是構造方法是私人屬性,也就是說只能在類內調用.所以直接new DB()的話會報錯,無法調用DB類內的私人屬性。往上看有一個靜態方法getInstance(),靜態方法是可以通過類名直接調用並且是不需要執行個體化對象的。比如DB::getInstance()就可以在類外調用這個方法了。
看getInstance()方法:
先判斷當前類是否被建立過,如果沒有就執行個體化並且賦值給靜態屬性$_instance,否則就直接返回$_instance,self::$_instance表示執行個體化過後DB類的控制代碼。也就是說不管調用多少次getInstance方法,最終也只會執行個體化一次DB類對象。
DB類單一職責就要求不能被clone,所以也私人化__clone方法
結論:單例模式可以很好的替代全域變數。雖然單例模式也存在和全域變數一樣的缺點 ,
比如依賴性,因此我們應當小心謹慎的使用單例模式
PHP設計模式之單例模式