PHP 單件模式
對(duì)一些類來說,只有一個(gè)實(shí)例是很重要的。比如一個(gè)數(shù)據(jù)庫連接類實(shí)例。我們?cè)趺礃硬拍鼙WC一個(gè)類只有一個(gè)實(shí)例并且這個(gè)實(shí)例易于被訪問呢?一個(gè)全局變量 使得一個(gè)對(duì)象可以被訪問,但它不能防止你實(shí)例化多個(gè)對(duì)象,而且全局變量會(huì)帶來意想不到的麻煩。一個(gè)更好的辦法是,讓類自身負(fù)責(zé)保存它的唯一實(shí)例。這個(gè)類可 以保證沒有其他實(shí)例可以被創(chuàng)建(通過截取創(chuàng)建新對(duì)象的請(qǐng)求),并且它可以提供一個(gè)訪問該實(shí)例的方法。這就是Singleton模式:保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)訪問它的全局訪問點(diǎn)。
請(qǐng)看下面一段代碼,一個(gè)數(shù)據(jù)庫連接類:
view plaincopy to clipboardprint? <?php class DbConn { // 私有靜態(tài)變量,保存DbConn類唯一實(shí)例 private static $instance; // 私有的構(gòu)造函數(shù),防止用戶直接實(shí)例化DbConn類 private function __construct() { // 這里初始化數(shù)據(jù)庫連接 } // 公有的靜態(tài)方法,獲取DbConn類的唯一實(shí)例 public static function getInstance() { if (!isset(self::$instance)) { self::$instance = new DbConn(); } return self::$instance; } // 私有的析構(gòu)函數(shù) private function __destruct() { // 這里關(guān)閉數(shù)據(jù)庫連接 } // 阻止用戶克隆DbConn類實(shí)例 public function __clone() { trigger_error('不允許Clone.', E_USER_ERROR); } ?> <?php class DbConn { // 私有靜態(tài)變量,保存DbConn類唯一實(shí)例 private static $instance;
// 私有的構(gòu)造函數(shù),防止用戶直接實(shí)例化DbConn類 private function __construct() { // 這里初始化數(shù)據(jù)庫連接 } // 公有的靜態(tài)方法,獲取DbConn類的唯一實(shí)例 public static function getInstance() { if (!isset(self::$instance)) { self::$instance = new DbConn(); } return self::$instance; } // 私有的析構(gòu)函數(shù) private function __destruct() { // 這里關(guān)閉數(shù)據(jù)庫連接 } // 阻止用戶克隆DbConn類實(shí)例 public function __clone() { trigger_error('不允許Clone.', E_USER_ERROR); } ?>
分析一下這段代碼,發(fā)現(xiàn)4個(gè)特征: 1.一個(gè)私有的靜態(tài)屬性 2.私有的構(gòu)造、析構(gòu)函數(shù) 3.一個(gè)公有的靜態(tài)方法獲取類的唯一實(shí)例 4.防止用戶克隆(__clone())類實(shí)例
這就是Singleton模式的特征,一個(gè)非常高效實(shí)用的模式。
下面一段代碼是測(cè)試例子。
view plaincopy to clipboardprint? <?php // 報(bào)錯(cuò) $test = new DbConn(); // OK $test = DbConn::getInstance(); // 報(bào)錯(cuò) $test_clone = clone($test); ?> |
|