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

《PHP設(shè)計(jì)模式介紹》第七章 策略模式(3)_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ù)庫連接就是這

樣本代碼

從一個(gè)多重的switch 條件判斷改變到策略模式是一個(gè)條件分解實(shí)例的經(jīng)典例子。整個(gè)測(cè)試的環(huán)境沒有變化;只是VarCache類的內(nèi)部改變了。

首先我們把你想要封裝在一個(gè)獨(dú)立的類的各種情況分隔出來。就前面的例子來說,你有三種變化的情況需要進(jìn)行考慮:‘string’, ‘numeric’, 和第三個(gè)‘serialize’。前面的例子中還在對(duì)象實(shí)例化的時(shí)候選擇了數(shù)據(jù)輸出的格式�;谶@個(gè)運(yùn)算法則,你需要?jiǎng)?chuàng)建一個(gè)API來封裝它。

你可以用以下的代碼開始:

class CacheWriter {
function store($file_handle, $var) {
die(‘abstract class-implement in concrete CacheWriter’);
}
}

這個(gè)就是PHP4版本的接口。(你可以從這個(gè)類進(jìn)行繼承來保證你使用的是子類,這樣做的話只是增加了一些系統(tǒng)的負(fù)載。尤其在基類CacheWriter是在另外一個(gè)文件定義的時(shí)候。負(fù)載增加得稍微多一些。)

基類CacheWriter 調(diào)用了store() 方式函數(shù)來引入文件處理資源和參數(shù)來進(jìn)行存儲(chǔ)。每一個(gè)實(shí)際的類都從執(zhí)行store()函數(shù), 但是不同的實(shí)例在store()函數(shù)里面使用的運(yùn)算法則是不一樣的,以便不同的數(shù)據(jù)類型生成的$cached_content是不同的。每一個(gè)運(yùn)算法則被當(dāng)作一個(gè)單獨(dú)的類來運(yùn)行。

前面的例子中的代碼被替換為:

class VarCache {
// ...
function _getTemplate() {
$template = ‘<?php $cached_content = ‘;
switch ($this->_type) {
case ‘string’:
$template .= “‘%s’;”;
break;
}
// ...
}
function set($value) {
$file_handle = fopen($this->_name.’.php’, ‘w’);
switch ($this->_type) {
case ‘string’:
$content = sprintf($this->_getTemplate()
,str_replace(“‘“,”\\’”,$value));
break;
// ...
}
fwrite($file_handle, $content);
fclose($file_handle);
}
}

針對(duì)每一個(gè)緩存的數(shù)據(jù)來型,你需要實(shí)例出相對(duì)應(yīng)的_getTemplate() 和

set() 方式函數(shù)到相對(duì)應(yīng)的類當(dāng)中。這里是StringCacheWriter:


class StringCacheWriter /* implements CacheWriter */ {
function store($file_handle, $string) {
$content = sprintf(
“<?php\n\$cached_content = ‘%s’;”
,str_replace(“‘“,”\\’”,$string));
fwrite($file_handle, $contents);
}
}

(因?yàn)镻HP 4不支持接口的使用,這里接口只是用注釋來簡單描述一下。)

這里我們得到另外一個(gè)運(yùn)算法則存儲(chǔ)“策略”。

class NumericCacheWriter /* implements CacheWriter */ {
function store($file_handle, $numeric) {
$content = sprintf(“<?php\n\$cached_content = %s;”
,(double)$numeric);
The Strategy Pattern 133
fwrite($file_handle, $content);
}
}
class SerializingCacheWriter /* implements CacheWriter */ {
function store($file_handle, $var) {
$content = sprintf(
“<?php\n\$cached_content = unserialize(stripslashes(‘%s’));”
,addslashes(serialize($var)));
fwrite($file_handle, $content);
}
}


通過把運(yùn)算法則封裝到交互的類中(同樣的API,多形性),你現(xiàn)在可以回過頭來通過策略設(shè)計(jì)模式重新執(zhí)行VarCache()類。這個(gè)時(shí)候經(jīng)過條件分解但是與原來非常類似的代碼可以繼續(xù)運(yùn)行了。

class VarCache {
var $_name;
var $_type;
function VarCache($name, $type=’serialize’) {
$this->_name = ‘cache/’.$name;
switch (strtolower($type)) {
case ‘string’: $strategy = ‘String’; break; case ‘numeric’: $strategy = ‘Numeric’; break; case serialize’:
default: $strategy = ‘Serializing’;
}
$strategy .= ‘CacheWriter’;
$this->_type =& new $strategy;
}
function isValid() {
return file_exists($this->_name.’.php’);
}
function get() {
if ($this->isValid()) {
include $this->_name.’.php’;
return $cached_content;
}
}
function set($value) {
$file_handle = fopen($this->_name.’.php’, ‘w’);
$this->_type->store($file_handle, $value);
fclose($file_handle);
}
}


通過創(chuàng)建實(shí)際的CacheWriter 類的實(shí)例并讓它幫定實(shí)際的$_type變量,你可以使用 $this->_type->store($file_handle, $value) 語句來寫入緩存數(shù)據(jù)。

緩存文件的時(shí)候,我們將不再關(guān)心初始化的時(shí)候是用什么運(yùn)算法則來存儲(chǔ)數(shù)據(jù)。

下面描述了定義策略設(shè)計(jì)模式的幾個(gè)特性:一系列的運(yùn)算法則,每個(gè)運(yùn)算法則都是封裝在獨(dú)立的類中。但是,每一個(gè)對(duì)象都是綁定到一個(gè)公共的容器對(duì)象中。并且,通過一個(gè)公共的API使用同樣的方式在進(jìn)行引用。而這個(gè)公共的API的運(yùn)行方式是與策略的選擇無關(guān)的。


評(píng)論

策略設(shè)計(jì)模式的功能是非常強(qiáng)大的 。本書到現(xiàn)在為止所說的其它的設(shè)計(jì)模式提供的都是應(yīng)用的基礎(chǔ)模塊功能,而 策略設(shè)計(jì)模式是目前第一個(gè)擁有設(shè)計(jì)模式和項(xiàng)目的遷移里面關(guān)鍵功能的設(shè)計(jì)模式。

它可以替換掉一個(gè)對(duì)象里面編寫復(fù)雜的部分,改變整個(gè)對(duì)象的運(yùn)行和性能,這點(diǎn)功能是非常強(qiáng)大的。另外,一個(gè)特定策略使用以后馬上就被清空了,這個(gè)使得剩下的API非常容易執(zhí)行。從根本上說,選用哪個(gè)運(yùn)算法則對(duì)于其它的代碼來說都是透明的。

互聯(lián)網(wǎng)上有這么一個(gè)說法“本質(zhì)上說,任何一個(gè)事情開始的時(shí)候都像在使用策略模式。”為什么呢?因?yàn)檫@個(gè)設(shè)計(jì)模式有效應(yīng)用了多形性的特點(diǎn),而這個(gè)也是面向?qū)ο缶幊套顝?qiáng)大的幾個(gè)方面之一。

相關(guān)的設(shè)計(jì)模式

策略模式和其它許多設(shè)計(jì)模式比較起來是非常類似的。策略模式和狀態(tài)模式最大的區(qū)別就是策略模式只是的條件選擇只執(zhí)行一次,而狀態(tài)模式是隨著實(shí)例參數(shù)(對(duì)象實(shí)例的狀態(tài))的改變不停地更改執(zhí)行模式。換句話說,策略模式只是在對(duì)象初始化的時(shí)候更改執(zhí)行模式,而狀態(tài)模式是根據(jù)對(duì)象實(shí)例的周期時(shí)間而動(dòng)態(tài)地改變對(duì)象實(shí)例的執(zhí)行模式。

注: 設(shè)計(jì)模式—狀態(tài)

Design Pattern—State

狀態(tài)設(shè)計(jì)模式允許一個(gè)對(duì)象實(shí)例因?yàn)橐粋(gè)內(nèi)部的狀態(tài)改變而改變其執(zhí)行模式。 因此,對(duì)象實(shí)例自身可以有效地改變其類定義。

油漆工設(shè)計(jì)模式(見第十二章) 在概念上正好和策略模式是相反的。借用GoF的一個(gè)推論,策略模式改變的是一個(gè)對(duì)象實(shí)例的核心的復(fù)雜操作,而油漆工設(shè)計(jì)模式改變的是一個(gè)對(duì)象實(shí)例的皮膚。

最后一個(gè)相關(guān)的設(shè)計(jì)模式是訪問者設(shè)計(jì)模式。在策略模式里面,你創(chuàng)建一個(gè)實(shí)際的選擇的策略的對(duì)象實(shí)例然后把它綁定到一個(gè)實(shí)例參數(shù)中;在訪問者模式里面,策略使用參數(shù)的方式進(jìn)行傳遞的。你可以想象下訪問者設(shè)計(jì)模式,它的設(shè)計(jì)思路和策略模式正好相反。

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

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