日韩天天综合网_野战两个奶头被亲到高潮_亚洲日韩欧美精品综合_av女人天堂污污污_视频一区**字幕无弹窗_国产亚洲欧美小视频_国内性爱精品在线免费视频_国产一级电影在线播放_日韩欧美内地福利_亚洲一二三不卡片区

《PHP設(shè)計模式介紹》第五章 注冊模式(3)_PHP教程

編輯Tag賺U幣
教程Tag:暫無Tag,歡迎添加,賺取U幣!

推薦:《PHP設(shè)計模式介紹》第四章 單件模式
幾乎所有面向?qū)ο蟮某绦蛑校傆幸粌蓚資源被創(chuàng)建出來,在程序應(yīng)用中持續(xù)被共享使用。例如,這樣的一個資源,在一個電子商務(wù)程序的數(shù)據(jù)庫連接中使用:這個連接在應(yīng)用程序啟動時初始化,程序于是


initRegistry()方法包含一個初始化為數(shù)組的靜態(tài)變量。這個靜態(tài)變量通過引用返回。在構(gòu)造函數(shù)中$_store實例變量被賦于通過initRegistry()函數(shù)返回的引用——即靜態(tài)數(shù)組。好!一個PHP4的類靜態(tài)變量產(chǎn)生了。

使用類靜態(tài)變量的實現(xiàn):

PHP5中,沒有必要自己實現(xiàn)類靜態(tài)變量,因為PHP5直接支持類靜態(tài)變量。因此,PHP5簡化了實現(xiàn)。而且,PHP5中引用、對象不再有PHP4中的意義,但是assertReference() 處理了這種差別,如果兩個變量指向同一個對象句柄也可以通過測試。

以下是為PHP5改寫的類似的Registry測試用例。

// PHP5
class RegistryMonoStatePHP5TestCase extends UnitTestCase {
function testRegistryMonoState() {
$this->assertCopy(
$reg = new RegistryMonoState
,$reg2 = new RegistryMonoState);
$this->assertFalse($reg->isValid(‘key’));
$this->assertNull($reg->get(‘key’));
$test_value = new TestObj;
$reg->set(‘key’, $test_value);
$this->assertReference($test_value, $reg2->get(‘key’));
}
}

以下是PHP5版本的使用靜態(tài)類變量的Registry類。

class RegistryMonoState {
protected static $store = array();
function isValid($key) {
return array_key_exists($key, RegistryMonoState::$store);
}
function get($key) {
if (array_key_exists($key, RegistryMonoState::$store))
return RegistryMonoState::$store[$key];
}
function set($key, $obj) {
RegistryMonoState::$store[$key] = $obj;
}
}

PHP5中用這種方式編碼Registry類的一個有趣的效果是你可以用相同的代碼使用實例或者靜態(tài)方法。以下是證明僅僅使用靜態(tài)方法的測試用例。

class RegistryMonoStatePHP5TestCase extends UnitTestCase {
function testRegistryMonoState() { /*...*/ }
function testRegistryMonoStateStaticCalls() {
$this->assertFalse(RegistryMonoState::isValid(‘key’));
$this->assertNull(RegistryMonoState::get(‘key’));
$test_value = new TestObj; RegistryMonoState::set(‘key’, $test_value);
$this->assertIdentical($test_value, RegistryMonoState::get(‘key’));
}

現(xiàn)在你已經(jīng)看到在PHP5中的靜態(tài)調(diào)用接口,下面讓我們在PHP4中實現(xiàn)相同的接口。在前面的PHP4“靜態(tài)類變量”部分,實現(xiàn)需要使用“函數(shù)靜態(tài)變量返回引用”來跟蹤。PHP4版本的靜態(tài)調(diào)用接口測試與PHP5版本的測試類似。

// PHP4
class RegistryStaticPHP4TestCase extends UnitTestCase {
function testRegistryStatic() {
$this->assertFalse(RegistryStatic::isValid(‘key’));
$this->assertNull(RegistryStatic::get(‘key’));
$test_value = ‘something’; RegistryStatic::set(‘key’, $test_value);
$this->assertReference($test_value, RegistryStatic::get(‘key’));
}
}

以下是符合測試要求的代碼實現(xiàn)。

class RegistryStatic {
function &_getRegistry() { static $store = array(); return $store;
}
function isValid($key) {
$store =& RegistryStatic::_getRegistry();
return array_key_exists($key, $store);
}
function &get($key) {
$store =& RegistryStatic::_getRegistry();
if (array_key_exists($key, $store))
return $store[$key];
}
function set($key, &$obj) {
$store =& RegistryStatic::_getRegistry();
$store[$key] =& $obj;
}
}


這個實現(xiàn)方法的重點是getRegistry()方法返回一個對靜態(tài)數(shù)組的引用。

$store =& RegistryStatic::_getRegistry();這一行,在隨后的函數(shù)中把變量$store通過引用賦給靜態(tài)數(shù)組,允許所有的函數(shù)可以靜態(tài)訪問數(shù)組,允許所有的方法可以被靜態(tài)調(diào)用。

也可以不使用PHP4“靜態(tài)類變量跟蹤”達(dá)到相同的效果:將原先的基于單件模式的Registry類與一個包裝類結(jié)合以達(dá)到允許靜態(tài)調(diào)用。這個類與testRegistryStatic()有相同的測試代碼,但是他的實現(xiàn)如下所示:

class RegistryStatic {
function isValid($key) {
$reg =& Registry::getInstance();
return $reg->isValid($key);
}
function &get($key) {
$reg =& Registry::getInstance();
return $reg->get($key);
}
function set($key, &$obj) {
$reg =& Registry::getInstance();
$reg->set($key, $obj);
}
}

結(jié)論:

雖然注冊模式簡化了對大量對象的訪問,但是仍然有許多問題——與全局變量聯(lián)合。你需要確定要求的屬性Key在訪問之已經(jīng)被初始化了,而且設(shè)置屬性的方法可以全局訪問,你的對象仍然可能在你的代碼的其他部分出乎意料的被替換掉。顯然,全局?jǐn)?shù)據(jù)非常有好處,方便,但是你需要時刻記住任何全局?jǐn)?shù)據(jù)都是有一些不安全的。


內(nèi)嵌的Registry模式

除了單獨(dú)使用注冊模式——如本章所示,Registry模式與其他對象結(jié)合時功能也是非常強(qiáng)大。例如:當(dāng)對象的創(chuàng)建代價非常昂貴(例如需要查詢大量數(shù)據(jù)庫來初始化對象)時,而且對象在這個應(yīng)用中被使用一次或多次,如果這樣,你能創(chuàng)建一個結(jié)合了工作模式 (見第三章) 和注冊模式 的“Finder”類以獲得已經(jīng)創(chuàng)建的對象的緩存而不用再次創(chuàng)建他們?

以下是一個Contact類,AddressBook類是工廠類。

class AddressBook {
function &findById($id) {
return new Contact($id);
}
}
class Contact {
function Contact($id) {
// expensive queries to create object using $id
}
// ... other methods
}

你可以在AddressBook類中插入Registry模式來提供緩存。代碼可以如下所示:

class AddressBook {
var $registry;
function AddressBook() {
$this->registry =& Registry::getInstance();
}
function &findById($id) {
if (!$this->registry->isValid($id)) {
$this->registry->set($id, new Contact($id));
}
return $this->registry->get($id);
}
}

AddressBook類的構(gòu)造函數(shù)將registry綁定到一個實例變量。當(dāng)創(chuàng)建了一個特定的ID并被findById()方法調(diào)用時,Registry被檢查以確定對象是否已經(jīng)被緩存。如果沒有,將創(chuàng)建一個新的對象并存儲在Registry中。被調(diào)用的對象將通過函數(shù)從Registry中取出并被返回。

分享:《PHP設(shè)計模式介紹》第三章 工廠模式
在面向?qū)ο缶幊讨? 最通常的方法是一個new操作符產(chǎn)生一個對象實例,new操作符就是用來構(gòu)造對象實例的。但是在一些情況下, new操作符直接生成對象會帶來一些問題。舉例來說, 許多類型對象的創(chuàng)造需

共3頁上一頁123下一頁
來源:模板無憂//所屬分類:PHP教程/更新時間:2008-08-22
相關(guān)PHP教程