把以下這段代碼加入到測(cè)試環(huán)境中以后,你可以確保每一個(gè)測(cè)試過程從開始的時(shí)候就各自獨(dú)立地運(yùn)行:
The Strategy Pattern 127
class VarCacheTestCase extends UnitTestCase { function setup() { @unlink(‘cache/foo.php’); } // ... }
現(xiàn)在緩存的文件在每一次測(cè)試執(zhí)行之前都沒刪除掉了,這保證了每一次測(cè)試運(yùn)行都是相互獨(dú)立的。(測(cè)試驅(qū)動(dòng)的開發(fā)更實(shí)用的方法是你可以寫一個(gè)VarCache::clear()方式函數(shù)去處理一個(gè)緩存的參數(shù)的清除工作。)
當(dāng)上一次代碼執(zhí)行出來的緩存結(jié)果被清除了,測(cè)試重新開始運(yùn)行,這意味著你可以繼續(xù)測(cè)試并編寫新的代碼。
class VarCacheTestCase extends UnitTestCase { function setup() { /* ... */ } function TestUnsetValueIsInvalid() { /* ... */ } function TestIsValidTrueAfterSet() { /* ... */ } function TestCacheRetainsValue() { $test_val = ‘test’.rand(1,100); $cache =& new VarCache(‘foo’); $cache->set($test_val); $this->assertEqual($test_val, $cache->get()); }
上面的測(cè)試驗(yàn)證VarCache::get()返回的值是否與用VarCache::set()設(shè)置的相同。
class VarCache { var $_name; function VarCache($name) { /* ... */ } function isValid() { /* ... */ } function get() { if ($this->isValid()) { return file_get_contents($this->_name.’.php’); } } function set($value) { $file_handle = fopen($this->_name.’.php’, ‘w’); fwrite($file_handle,$value); fclose($file_handle); } }
128
The Strategy Pattern
通過黑體字部分的代碼,VarCache::set() 方式函數(shù)把參數(shù)$value的內(nèi)容寫到文件中,并用VarCache::get() 方式函數(shù)通過file_get_content() 從文件中把內(nèi)容讀取出來.
從目前的執(zhí)行情況來看,對(duì)于字符串和數(shù)字的操作是沒有問題的,但是對(duì)于更復(fù)雜的參數(shù)比如數(shù)組和對(duì)象,執(zhí)行起來就會(huì)出現(xiàn)問題了。我們用下面的代碼進(jìn)行處理:
class VarCacheTestCase extends UnitTestCase { // ... function TestStringFailsForArray() { $test_val = array(‘one’,’two’); $cache =& new VarCache(‘foo’); $cache->set($test_val); $this->assertError(‘Array to string conversion’); $this->assertNotEqual($test_val, $cache->get()); $this->assertEqual(‘a(chǎn)rray’,strtolower($cache->get())); }
由于篇幅的關(guān)系,我們直接調(diào)到這個(gè)執(zhí)行過程的結(jié)束部分,它隨后也將實(shí)現(xiàn)策略式的判斷。
這里就是增加一系列操作用來完善VarCache的地方。
class VarCache { //... function get() { if ($this->isValid()) { include $this->_name.’.php’; return $cached_content; } //... }
在這里關(guān)鍵性的改變是get() 方式函數(shù)(并且讓PHP去驗(yàn)證有效性。
同時(shí),get()返回參數(shù)$cached_content的值,所以無論set() 如果操作,它必須設(shè)置這個(gè)變量!
因此,對(duì)于數(shù)字來說,執(zhí)行出來是什么樣的結(jié)果呢?
class VarCache { //... function set($value) { $file_handle = fopen($this->_name.’.php’, ‘w’); $template = ‘<?php $cached_content = %s;’; $content = sprintf($template The Strategy Pattern 129 ,(float)$value); fwrite($file_handle, $content); fclose($file_handle); } }
看起來對(duì)于一個(gè)數(shù)字,執(zhí)行起來是沒有問題的,那么對(duì)于字符串如何呢?對(duì)于字符串,緩存文件的數(shù)據(jù)編寫方式就必須用= ‘%s’;結(jié)尾而不是= %s;。所以在這里我們需要引入一個(gè)“type” 參數(shù):它用來指定緩存的數(shù)據(jù)類型是一個(gè)整型還是字符串。為了更容易地增加更多的數(shù)據(jù)類型,我們分別在set()和_getTemplate()函數(shù)增加一個(gè)case 判斷。
class VarCache { var $_name; var $_type; function VarCache($name, $type=’string’) { $this->_name = ‘cache/’.$name; $this->_type = $type; } // ... function _getTemplate() { $template = ‘<?php $cached_content = ‘; switch ($this->_type) { case ‘string’: $template .= “‘%s’;”; break; case ‘numeric’: $template .= ‘%s;’; break; default: trigger_error(‘invalid cache type’); } return $template; } function set($value) { $file_handle = fopen($this->_name.’.php’, ‘w’); switch ($this->_type) { case ‘string’: $content = sprintf($this->_getTemplate() ,str_replace(“‘“,”\\’”,$value)); break; case ‘numeric’: $content = sprintf($this->_getTemplate() ,(float)$value); break; default: trigger_error(‘invalid cache type’); } fwrite($file_handle, $content); fclose($file_handle); } }
130
The Strategy Pattern
出處:
責(zé)任編輯:bluehearts
上一頁 php設(shè)計(jì)模式介紹之策略模式 [2] 下一頁 php設(shè)計(jì)模式介紹之策略模式 [4]
◎進(jìn)入論壇網(wǎng)絡(luò)編程版塊參加討論
|