例子
舉例子說明,讓我們做一個(gè)存儲(chǔ)PHP參數(shù)的cache。這個(gè)cahce類需要把變量以PHP識(shí)別的方式寫入到一個(gè)文件當(dāng)中,所以你可以在以后加載該文件并使用它。這個(gè)類還應(yīng)該可以讓你為每個(gè)數(shù)據(jù)加個(gè)標(biāo)識(shí)符和存儲(chǔ)的方式。
數(shù)據(jù)緩存
注:緩存是為了在接下來的操作中繼續(xù)使用而對(duì)資源進(jìn)行緩存。你可以通過建立和使用緩存來節(jié)省直接從原數(shù)據(jù)庫獲取數(shù)據(jù)的時(shí)間。這方面的例子最常見的就是訪問數(shù)據(jù)庫或者解析大的XML文檔,或者大的配置文件。
緩存也會(huì)出現(xiàn)一個(gè)問題:你的緩存可能會(huì)失去與原數(shù)據(jù)的同步;蛘呔彺嫘枰褂锰鄡(nèi)存。
最開始,我們開發(fā)一個(gè)緩存操作,并不使用策略模式。
因?yàn)槟憧赡苄枰彺娴牟恢挂粋(gè)值,所以你需要使用標(biāo)識(shí)符來標(biāo)識(shí)出你需要指定的元素。在這個(gè)例子中,標(biāo)識(shí)符就是’application_config’。下面試一個(gè)如果使用cache的例子。
// PHP4 $config_cache =& new VarCache(‘a(chǎn)pplication_config’); if ($config_cache->isValid()) { $config = $config_cache->get(); } else { $config = slow_expensive_function_to_get_config(); $config_cache->set($config); }
這個(gè)代碼生成了一個(gè)新的VarCache對(duì)象存放在$config_cache變量里面。這個(gè)數(shù)據(jù)在緩存中的標(biāo)識(shí)符是 ‘a(chǎn)pplication_config’。如果在緩存里面有這個(gè)數(shù)據(jù), isValid() 將返回真( true )并且獲取緩存中的數(shù)據(jù)。反之,值被重新獲取并寫入緩存當(dāng)中,以便下次使用。
按照一般的需求,讓我們開始編寫這段代碼來進(jìn)行測(cè)試。首先,如果緩存中沒有該數(shù)據(jù), isValid() 方式函數(shù)應(yīng)該返回非值(false)。
class VarCacheTestCase extends UnitTestCase { function TestUnsetValueIsInvalid() { $cache =& new VarCache(‘foo’); $this->assertFalse($cache->isValid()); }
因?yàn)閂arCache現(xiàn)在沒有代碼,所以最簡單的方式就是先構(gòu)造一個(gè)方式函數(shù)。
class VarCache { function isValid() {} }
這樣,我們就可以繼續(xù)了。
class VarCacheTestCase extends UnitTestCase { function TestUnsetValueIsInvalid() { /* ... */ } function TestIsValidTrueAfterSet() { $cache =& new VarCache(‘foo’); $cache->set(‘bar’); $this->assertTrue($cache->isValid()); }
上面的測(cè)試校驗(yàn)了緩存的數(shù)據(jù)是否是可用的。
開始編寫cache類的主要部分。VarCache 引入一個(gè)標(biāo)識(shí)符, 所以constructor了一個(gè)應(yīng)該記錄它的對(duì)象實(shí)例。這里面還有一個(gè)set()的方式函數(shù),用來把數(shù)據(jù)存入緩存,或者當(dāng)數(shù)據(jù)存在時(shí),修改緩存當(dāng)中的數(shù)據(jù)。
class VarCache { var $_name; function VarCache($name) { $this->_name = ‘cache/’.$name; } function isValid() { return file_exists($this->_name.’.php’); } function set() { $file_handle = fopen($this->_name.’.php’, ‘w’); fclose($file_handle); } }
對(duì)象實(shí)例的參數(shù)$_name 存放了緩存的標(biāo)識(shí)符。在這個(gè)簡單的操作中, $_name 被用來生成文件名(在實(shí)際的使用可能會(huì)數(shù)據(jù)庫或者其它的數(shù)據(jù)源代替) set() 使用 fopen() 和 fclose() 來 “訪問” 基于$_name的文件。當(dāng)調(diào)用set()后, file_exists()在VarCache::isValid()里面調(diào)用返回真(true)。
運(yùn)行這個(gè)測(cè)試來產(chǎn)生一個(gè)我們預(yù)期的結(jié)果;但是實(shí)際情況是報(bào)錯(cuò)!為什么呢?第一次運(yùn)新的時(shí)候沒有生成文件,所以第二次運(yùn)行的時(shí)候找不到文件,顯然我們不希望這種情況出現(xiàn)。我們期望的是每一次運(yùn)行代碼都是互不影響的。
幸運(yùn)的是,把總體測(cè)試框架和特定功能的簡單測(cè)試結(jié)合起來,我們就可以得到靈活的測(cè)試環(huán)境,并且在以后的測(cè)試中方便地使用。UnitTestCase::setUp()實(shí)現(xiàn)框架的初始化,而UnitTestCase::tearDown()實(shí)現(xiàn)具體的測(cè)試過程。
出處:
責(zé)任編輯:bluehearts
上一頁 php設(shè)計(jì)模式介紹之策略模式 [1] 下一頁 php設(shè)計(jì)模式介紹之策略模式 [3]
◎進(jìn)入論壇網(wǎng)絡(luò)編程版塊參加討論
|