一、什麼是單例模式?1、含義 作為對象的創建模式,單例模式確保某一個類只有一個實例,而且自行實例化並向整個系統全局地提供這個實例。它不會創建實例副本,而是會向單例類內部存儲的實例返回一個引用。2、單例模式的三個要點:(1). 需要一個保存類的唯一實例的靜態成員變數:private static $_ ...
一、什麼是單例模式?
1、含義
作為對象的創建模式,單例模式確保某一個類只有一個實例,而且自行實例化並向整個系統全局地提供這個實例。它不會創建實例副本,而是會向單例類內部存儲的實例返回一個引用。
2、單例模式的三個要點:
(1). 需要一個保存類的唯一實例的靜態成員變數:
private static $_instance;
(2). 構造函數和克隆函數必須聲明為私有的,防止外部程式new類從而失去單例模式的意義:
private function __construct()
{
$this->_db = pg_connect('xxxx');
}
private function __clone()
{
}//覆蓋__clone()方法,禁止克隆
(3). 必須提供一個訪問這個實例的公共的靜態方法(通常為getInstance方法),從而返回唯一實例的一個引用
public static function getInstance()
{
if(! (self::$_instance instanceof self) )
{
self::$_instance = new self();
}
return self::$_instance;
}
二、為什麼要使用單例模式?
多數人都是從單例模式的字面上的意思來理解它的用途, 認為這是對系統資源的節省, 可以避免重覆實例化, 是一種"計劃生育". 而PHP每次執行完頁面都是會從記憶體中清理掉所有的資源. 因而PHP中的單例實際每次運行都是需要重新實例化的, 這樣就失去了單例重覆實例化的意義了. 單單從這個方面來說, PHP的單例的確有點讓各位失望. 但是單例僅僅只有這個功能和應用嗎? 答案是否定的,我們一起來看看。
php的應用主要在於資料庫應用, 所以一個應用中會存在大量的資料庫操作, 在使用面向對象的方式開發時(廢話), 如果使用單例模式, 則可以避免大量的new 操作消耗的資源。
如果系統中需要有一個類來全局控制某些配置信息, 那麼使用單例模式可以很方便的實現. 這個可以參看zend Framework的FrontController部分。
在一次頁面請求中, 便於進行調試, 因為所有的代碼(例如資料庫操作類db)都集中在一個類中, 我們可以在類中設置鉤子, 輸出日誌,從而避免到處var_dump, echo。
1、PHP缺點:
PHP語言是一種解釋型的腳本語言,這種運行機制使得每個PHP頁面被解釋執行後,所有的相關資源都會被回收。也就是說,PHP在語言級別上沒有辦法讓某個對象常駐記憶體,這和asp.net、Java等編譯型是不同的,比如在Java中單例會一直存在於整個應用程式的生命周期里,變數是跨頁面級的,真正可以做到這個實例在應用程式生命周期中的唯一性。然而在PHP中,所有的變數無論是全局變數還是類的靜態成員,都是頁面級的,每次頁面被執行時,都會重新建立新的對象,都會在頁面執行完畢後被清空,這樣似乎PHP單例模式就沒有什麼意義了,所以PHP單例模式我覺得只是針對單次頁面級請求時出現多個應用場景並需要共用同一對象資源時是非常有意義的。
2、單例模式在PHP中的應用場合:
(1)、應用程式與資料庫交互
一個應用中會存在大量的資料庫操作,比如過資料庫句柄來連接資料庫這一行為,使用單例模式可以避免大量的new操作,因為每一次new操作都會消耗記憶體資源和系統資源。
(2)、控制配置信息
如果系統中需要有一個類來全局控制某些配置信息, 那麼使用單例模式可以很方便的實現.
三、如何實現單例模式?
1、普通的資料庫訪問例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?php
......
//初始化一個資料庫句柄
$db = new DB(...);
//添加用戶信息
$db ->addUserInfo(...);
......
//在函數中訪問資料庫,查找用戶信息
function getUserInfo()
{
$db = new DB(...); //再次new 資料庫類,和資料庫建立連接
$db = query(....); //根據查詢語句訪問資料庫
}
?>
|
2、應用單例模式對資料庫進行操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<?php
class DB
{
private $_db ;
private static $_instance ;
private function __construct(...)
{
$this ->_db = pg_connect(...); //postgrsql
}
private function __clone() {}; //覆蓋__clone()方法,禁止克隆
public static function getInstance()
{
if (! (self:: $_instance instanceof self) ) {
self:: $_instance = new self();
}
return self:: $_instance ;
}
public function addUserInfo(...)
{
}
public function getUserInfo(...)
{
}
}
//test
$db = DB::getInstance();
$db ->addUserInfo(...);
$db ->getUserInfo(...);
?>
|
下麵的代碼是PDO操作資料庫類的一個封裝,採用了單例模式: