《PHP設(shè)計(jì)模式介紹》第四章 單件模式(3)_PHP教程
推薦:《PHP設(shè)計(jì)模式介紹》第三章 工廠模式在面向?qū)ο缶幊讨? 最通常的方法是一個(gè)new操作符產(chǎn)生一個(gè)對象實(shí)例,new操作符就是用來構(gòu)造對象實(shí)例的。但是在一些情況下, new操作符直接生成對象會帶來一些問題。舉例來說, 許多類型對象的創(chuàng)造需
PHP5中的單件模式
PHP5中更容易實(shí)現(xiàn)單件模式,PHP5對于類內(nèi)部變量和函數(shù)的訪問控制被加強(qiáng)了。將DbConn::_construct()構(gòu)造方法設(shè)置為私有(private),這個(gè)類就不能被直接實(shí)例化。用UML圖表示,PHP5的DbConn單件模式如下:
組合使用靜態(tài)方法和靜態(tài)變量保持這個(gè)實(shí)例,并且設(shè)置構(gòu)造函數(shù)為私有,以防止直接實(shí)例化類而創(chuàng)建實(shí)例,代碼如下:
class DbConn {
/**
* static property to hold singleton instance
*/
static $instance = false;
/**
* constructor
* private so only getInstance() method can instantiate
* @return void
*/
private function __construct() {}
/**
* factory method to return the singleton instance
* @return DbConn
*/
public function getInstance() {
if (!DbConn::$instance) {
DbConn::$instance = new DbConn;
}
return DbConn::$instance;
}
}
結(jié)論
現(xiàn)在你已經(jīng)看到幾種單件設(shè)計(jì)模式的實(shí)現(xiàn)方式了,當(dāng)你著眼于實(shí)現(xiàn)這個(gè)設(shè)計(jì)模式時(shí)候,我們要仔細(xì)權(quán)衡考慮。
首先,一個(gè)單件對象不是一個(gè)“很好的”全局變量。舉例來說,如果一個(gè)方法需要一個(gè)單件對象,更顯而易見的用法是把它當(dāng)作一個(gè)參數(shù)傳遞來使用。
同樣,因?yàn)樗梢栽?ldquo;全局”得到使用,你很容易就會將所有種類的“常用函數(shù)”放置到一個(gè)單件類中。這個(gè)是你需要避免的,需要的時(shí)候,你才把函數(shù)封裝單件類中。
Monostate Pattern(單態(tài)模式):類單件模式
有時(shí)候,我們需要這樣一個(gè)類,所有類的實(shí)例都共享它的全局狀態(tài)――換句話說,它所產(chǎn)生的任何實(shí)例返回嚴(yán)格一致的信息。和單件模式類似,這是一種叫做MonoState(單態(tài))的模式。在PHP中,你使用一種優(yōu)美的引用技巧來綁定全局?jǐn)?shù)據(jù),通過把一個(gè)全局變量綁定到一個(gè)實(shí)例變量來實(shí)現(xiàn)MonoState。
舉個(gè)例子,讓我們創(chuàng)建一個(gè)全局應(yīng)用配置類。無論你用MonoState類的哪個(gè)實(shí)例,你都能得到同樣的值。
下面的測試代碼用來驗(yàn)證次功能:
| // PHP4 function TestApplConfig() { $this->assertIsA( $obj1 =& new ApplicationConfig, ‘ApplicationConfig’); $this->assertIsA( $obj2 =& new ApplicationConfig, ‘ApplicationConfig’); $test_val = ‘/path/to/cache’.rand(1,100); $obj1->set(‘cache_path’, $test_val); $this->assertEqual($test_val, $obj2->get(‘cache_path’)); } |
下面這段代碼實(shí)現(xiàn)了MonoState:
| class ApplicationConfig { var $_state; function ApplicationConfig() { $key = ‘__stealth_singleton_state_index__’; if (!(array_key_exists($key, $GLOBALS) && is_array($GLOBALS[$key]))) { $GLOBALS[$key] = array(); } $this->_state =& $GLOBALS[$key]; } function set($key, $val) { $this->_state[$key] = $val; } function get($key) { if (array_key_exists($key, $this->_state)) { return $this->_state[$key]; } } |
這個(gè)技巧能夠在任何PHP的自動全局(superglobal)數(shù)組使用,尤其在用戶消息隊(duì)列$_SESSION中有很顯著的效果。MonoState能通過你的代碼為用戶存儲一系列的使用信息(你要顯示的信息可能是從另外一個(gè)頁面?zhèn)魅氲?。$_SESSION是一個(gè)存儲這些信息的好地方,以方便這些信息在頁面跳轉(zhuǎn)后能持續(xù)使用。
這個(gè)技巧的核心是$this->state =& $GLOBALS[$key]; 。在確定$GLOBALS[$key]是一個(gè)數(shù)組后,代碼綁定一個(gè)全局?jǐn)?shù)組的引用給類變量$this->state。從而,任何$this->state的改變都自然而言地同步到全局?jǐn)?shù)組,包括類的其它實(shí)例。Test創(chuàng)建了MonoStatel類的兩個(gè)不同實(shí)例,改變其中一個(gè),驗(yàn)證另外一個(gè)是否也一起被改變了。這段代碼很簡單的選擇了這個(gè)靜態(tài)數(shù)組$instancede的第一個(gè)元素,用來保持單件DbConns實(shí)例的引用。Zend 1引擎在PHP4中不能存儲靜態(tài)變量的引用 (請看http://www.php.net/manual/en/language.variables.scope.php#AEN3609)。使用一個(gè)工作區(qū)存儲靜態(tài)數(shù)組,并且將這個(gè)單件實(shí)例的引用放置到一個(gè)已知的數(shù)組中。getInstance()方法如下:提示在DbConn的構(gòu)造函數(shù)中,你可能對$fromGetInstance的默認(rèn)參數(shù)感到疑惑。在對象被直接實(shí)例化時(shí),它能夠提供(很微弱的)保護(hù):除非這個(gè)默認(rèn)值變成e (在PHP的數(shù)學(xué)常量中 M_E = 2.718281828459),否則這段代碼會報(bào)錯。這段代碼直接創(chuàng)建了一個(gè) DbConn 的實(shí)例,將會引起PHP報(bào)錯。為了讓代碼更穩(wěn)定,我們用PCRE正則表達(dá)式來匹配報(bào)錯信息。(顯示報(bào)錯信息的確切措詞并不重要。)分享:《PHP設(shè)計(jì)模式介紹》第二章 值對象模式在所有的最簡單的程序中,大多數(shù)對象都有一個(gè)標(biāo)識,一個(gè)重要的商業(yè)應(yīng)用對象,例如一個(gè)Customer或者一個(gè)SKU,有一個(gè)或者更多的屬性---id,name,email地址,這樣可以把它從同一個(gè)類的其他實(shí)例區(qū)分開
- PHPNOW安裝Memcached擴(kuò)展方法詳解
- php記錄頁面代碼執(zhí)行時(shí)間
- PHP中獎概率的抽獎算法程序代碼
- apache設(shè)置靜態(tài)文件緩存方法介紹
- php對圖像的各種處理函數(shù)代碼小結(jié)
- PHP 關(guān)于訪問控制的和運(yùn)算符優(yōu)先級介紹
- 關(guān)于PHP語言構(gòu)造器介紹
- php/js獲取客戶端mac地址的實(shí)現(xiàn)代碼
- php5.5新數(shù)組函數(shù)array_column使用
- PHP preg_match的匹配多國語言的技巧
- php 中序列化和json使用介紹
- php采集文章中的圖片獲取替換到本地
PHP教程Rss訂閱編程教程搜索
PHP教程推薦
- php實(shí)現(xiàn)單鏈表的實(shí)例代碼
- 關(guān)于二級目錄拖拽排序的實(shí)現(xiàn)(源碼示例下載)
- 讓你的PHP引擎全速運(yùn)轉(zhuǎn)的三個(gè)簡單絕招
- setcookie中Cannot modify header information-headers already sent by錯誤的解決方法詳解
- PHP數(shù)據(jù)庫備份類
- PHP技巧:優(yōu)化動態(tài)網(wǎng)頁技術(shù)PHP程序的12條技巧
- ajax完美實(shí)現(xiàn)兩個(gè)網(wǎng)頁 分頁功能的實(shí)例代碼
- php實(shí)現(xiàn)gb2312和unicode間編碼轉(zhuǎn)換
- php自動識別文字字符串編碼并轉(zhuǎn)為目標(biāo)編碼
- 創(chuàng)建XML Http Request對象兩個(gè)的方法
- 相關(guān)鏈接:
- 教程說明:
PHP教程-《PHP設(shè)計(jì)模式介紹》第四章 單件模式(3)
。