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

《PHP設(shè)計(jì)模式介紹》第七章 策略模式(2)_PHP教程

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

推薦:《PHP設(shè)計(jì)模式介紹》第六章 偽對(duì)象模式
面向?qū)ο蟮木幊讨载S富多彩,部分是由于對(duì)象間的相互聯(lián)系與作用。一個(gè)單一的對(duì)象就能封裝一個(gè)復(fù)雜的子系統(tǒng),使那些很復(fù)雜的操作能夠通過一些方法的調(diào)用而簡化。(無所不在的數(shù)據(jù)庫連接就是這

把一下這段代碼加入到測試環(huán)境中以后,你可以確保每一個(gè)測試過程從開始的時(shí)候就各自獨(dú)立地運(yùn)行:


The Strategy Pattern 127
class VarCacheTestCase extends UnitTestCase {
function setup() {
@unlink(‘cache/foo.php’);
}
// ...
}


現(xiàn)在緩存的文件在每一次測試執(zhí)行之前都沒刪除掉了,這保證了每一次測試運(yùn)行都是相互獨(dú)立的。(測試驅(qū)動(dòng)的開發(fā)更實(shí)用的方法是你可以寫一個(gè)VarCache::clear()方式函數(shù)去處理一個(gè)緩存的參數(shù)的清除工作。)

當(dāng)上一次代碼執(zhí)行出來的緩存結(jié)果被清除了,測試重新開始運(yùn)行,這意味著你可以繼續(xù)測試并編寫新的代碼。

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());
}


上面的測試驗(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);
}
}


通過黑體字部分的代碼,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(‘array’,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);
}
}

現(xiàn)在,構(gòu)造函數(shù)增加了第二個(gè)可選的參數(shù)用來確定第一個(gè)參數(shù)的數(shù)據(jù)類型是數(shù)字類型還是字符串。這個(gè)類的最終形式變?yōu)檎埧聪旅娲a,包括了一個(gè)‘serialize’ 用來存儲(chǔ)數(shù)據(jù)、對(duì)象等復(fù)雜數(shù)據(jù)的存儲(chǔ)類型。

class VarCache {
var $_name;
var $_type;
function VarCache($name, $type=’serialize’) {
$this->_name = ‘cache/’.$name;
$this->_type = $type;
}
function isValid() {
return file_exists($this->_name.’.php’);
}
function get() {
if ($this->isValid()) {
include $this->_name.’.php’
return $cached_content;
}
}
function _getTemplate() {
$template = ‘<?php $cached_content = ‘;
switch ($this->_type) {
case ‘string’:
$template .= “‘%s’;”;
break;
case ‘serialize’:
$template .= “unserialize(stripslashes(‘%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 ‘serialize’:
$content = sprintf($this->_getTemplate()
,addslashes(serialize($value)));
break;
case ‘numeric’:
$content = sprintf($this->_getTemplate()
,(float)$value);
break;
default:
trigger_error(‘invalid cache type’);
}
fwrite($file_handle, $content);
The Strategy Pattern 131
fclose($file_handle);
}
}

請注意_getTemplate()和set() 函數(shù)中的case判斷語句。它們都是基于同一個(gè)$_type 實(shí)例參數(shù)的。get() 函數(shù)中卻沒有受到$_type的影響,所以看起來因?yàn)榇鎯?chǔ)的數(shù)據(jù)類型的變化只影響到數(shù)據(jù)的存儲(chǔ)過程。同時(shí),多重的case條件判斷也是一個(gè)提示,這個(gè)地方如果使用了策略的設(shè)計(jì)模式會(huì)更好。

分享:《PHP設(shè)計(jì)模式介紹》第五章 注冊模式
我們通常認(rèn)為避免使用全局變量是一種好的選擇,因此,對(duì)象經(jīng)常被作為參數(shù)從一段代碼傳遞到另一段。但是傳遞實(shí)例的一個(gè)問題就是對(duì)象有時(shí)候不知道將要傳遞給誰——?經(jīng)過一個(gè)函數(shù)后才被傳

來源:模板無憂//所屬分類:PHP教程/更新時(shí)間:2008-08-22
相關(guān)PHP教程