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

《PHP設(shè)計(jì)模式介紹》第十章 規(guī)范模式_PHP教程

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

推薦:《PHP設(shè)計(jì)模式介紹》第九章 觀測(cè)模式
一些面向?qū)ο蟮木幊谭绞�,提供了一種構(gòu)建對(duì)象間復(fù)雜網(wǎng)絡(luò)互連的能力。當(dāng)對(duì)象們連接在一起時(shí),它們就可以相互提供服務(wù)和信息。 通常來(lái)說(shuō),當(dāng)某個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),你仍然需要對(duì)象之間能互

在一個(gè)應(yīng)用軟件的成型過(guò)程中,一些意想不到的商業(yè)邏輯到處出現(xiàn)。比如,基于價(jià)格的考慮,這個(gè)任務(wù)必須減少項(xiàng)目;而那個(gè)任務(wù)也因?yàn)殇N(xiāo)售稅而必須選擇合適的比率;而其它的任務(wù)也必須因?yàn)槠渌奶貏e條件而終止。一些商業(yè)規(guī)則是簡(jiǎn)單的,只需要不到一兩個(gè)布爾比較關(guān)系就夠了,然而它的規(guī)則可能需要費(fèi)時(shí)的估計(jì),需要查詢(xún)數(shù)據(jù)庫(kù)或者用戶(hù)輸入數(shù)據(jù)來(lái)引導(dǎo)。

通過(guò)書(shū)寫(xiě)代碼可以把抽象(比如一條商業(yè)規(guī)則)轉(zhuǎn)化為具體可見(jiàn)的東西。但是抽象物(比如購(gòu)物方式,稅率,或者計(jì)算海運(yùn)費(fèi)等等)都有其進(jìn)化的方式,而且這些改變很容易難倒一個(gè)不幸運(yùn)的開(kāi)發(fā)人員。為了保證安全可靠——到目前為止你在這本書(shū)所看到的——盡可能的分離封裝那些容易改變的模塊是個(gè)很完美的想法。而且,這的確也一個(gè)明智的應(yīng)對(duì)商業(yè)規(guī)則的策略。

問(wèn)題描述

有沒(méi)有明確的方式來(lái)封裝商業(yè)邏輯呢?有沒(méi)有一個(gè)容易改寫(xiě)和重用的技術(shù)呢?

解決方案

規(guī)范模式是為驗(yàn)證和選擇而開(kāi)發(fā)的:

確認(rèn)一個(gè)特殊的對(duì)象是否滿(mǎn)足一定的標(biāo)準(zhǔn)

從集合中選擇出滿(mǎn)足給定標(biāo)準(zhǔn)的元素。

規(guī)范模式能讓你有效的組織這些標(biāo)準(zhǔn),并在你的應(yīng)用程序中靈活的使用他們。

代碼重構(gòu)技術(shù)已經(jīng)激發(fā)你的興趣,你決定使用它來(lái)提升代碼的清晰度和重用性。規(guī)范模式通過(guò)系統(tǒng)化進(jìn)一步的深化了這一步,它系統(tǒng)把這個(gè)結(jié)構(gòu)分解成一個(gè)個(gè)單獨(dú)的對(duì)象,這些對(duì)象能夠很方便的插入到你的應(yīng)用程序的合適地方。很多情況下,在你的應(yīng)用程序里,規(guī)范對(duì)象是參數(shù)化的,而且經(jīng)常被組合在一起來(lái)構(gòu)建復(fù)雜的合乎邏輯的表達(dá)式。

相關(guān)知識(shí)

Eric Evans 和 Martin Fowler 發(fā)表過(guò)一篇關(guān)于規(guī)范模型的文章,地址是:

http://www.martinfowler.com/apsupp/spec.pdf

這個(gè)模式在Eric Evans的書(shū)本《動(dòng)態(tài)驅(qū)動(dòng)設(shè)計(jì)》(“Domain Driven Design”)的第224到273頁(yè)有詳細(xì)的介紹。

為了合理的全面覆蓋這個(gè)模式,這章被組織成合乎邏輯的三部分。第一部分通過(guò)一個(gè)純粹的實(shí)例來(lái)說(shuō)明基本的模式概念。(Evans 和 Fowler 把這個(gè)稱(chēng)為為“硬編碼規(guī)范Hard Coded Specification”)。接下來(lái)的部分演示了如何構(gòu)建一個(gè)參數(shù)化規(guī)范模型,它提供了一個(gè)更加動(dòng)態(tài)和靈活的框架來(lái)實(shí)現(xiàn)規(guī)范模式(或者因此而稱(chēng)為“參數(shù)化規(guī)范”)的重用。最后一部分,我們開(kāi)發(fā)了一個(gè)“方案工廠”(Policy Factory),它把許多規(guī)范對(duì)象集中成一個(gè)易于使用的包(package)。

Traveling to Warm Destinations(到溫暖的目的地去旅行)

最近,我和我的家人計(jì)劃去度一個(gè)假期,我的妻子想去一個(gè)“溫暖的地方”。雖然有無(wú)數(shù)旅行相關(guān)的站點(diǎn),但是在我們?cè)L問(wèn)過(guò)的站點(diǎn)中沒(méi)有一個(gè)站點(diǎn)能夠?yàn)槊恳粋(gè)目的地提供詳細(xì)的天氣信息。沒(méi)辦法,我們不得不轉(zhuǎn)到weather.com然后開(kāi)始搜索,這是十分的不方便的�,F(xiàn)在讓我們來(lái)改變這種情況,為一個(gè)假定的旅行站點(diǎn)增加一個(gè)天氣搜索功能。在這里我們是用規(guī)范模式這個(gè)指南來(lái)引導(dǎo)你編碼,從而比較旅行者期望的最低溫度和許多目的地的平均溫度

首先,我們創(chuàng)建一些非常簡(jiǎn)單的對(duì)象。第一個(gè)是旅行者(a Traveler),它存儲(chǔ)了首選的最低溫度。

// PHP5
class Traveler {
public $min_temp;
}

接下來(lái)我們創(chuàng)建一個(gè)對(duì)象來(lái)表示目的地(Destination)。由于平均溫度是一個(gè)關(guān)鍵的標(biāo)準(zhǔn),目的地的構(gòu)建函數(shù)(__constructor)應(yīng)該得到一個(gè)十二維的數(shù)組,該數(shù)組的每一個(gè)值對(duì)應(yīng)一年里面每個(gè)月的平均溫度。

class Destination {
protected $avg_temps;
public function __construct($avg_temps) {
$this->avg_temps = $avg_temps;
}
}

目的地(Destination)同樣也還要一個(gè)方法,通過(guò)調(diào)用這個(gè)方法能夠得到這個(gè)目的地在指定月份的平均溫度。

class Destination {
//...
public function getAvgTempByMonth($month) {
$key = (int)$month - 1;
if (array_key_exists($key, $this->avg_temps)) {
return $this->avg_temps[$key];
}
}
}

最后,一次旅行(類(lèi)Trip)就由一個(gè)旅行者(類(lèi)Traveler),一個(gè)目的地(類(lèi)Destination)和一個(gè)日期(a Date)聯(lián)合組成。

class Trip {
public $date;
public $traveler;
public $destination;
}

給出上面這些對(duì)象,你就可以通過(guò)Trip::date得到旅行的月份,并且你能夠比較目的地的月平均溫度和旅行者期望的最低溫度。(這個(gè)比較可能不是特別的復(fù)雜,但是你還是需要你自己親自去實(shí)現(xiàn))

讓我們看看如何用規(guī)范模式實(shí)現(xiàn)“溫暖目的地”的商業(yè)邏輯,并且看看如何應(yīng)用這個(gè)模式來(lái)驗(yàn)證每一個(gè)目的地并選擇出所有合適的目的地。

樣本代碼

規(guī)范模式的核心是一個(gè)帶有IsSatisfiedBy()方法的對(duì)象,IsSatisfiedBy()方法接收一個(gè)變量來(lái)評(píng)估并且返回一個(gè)基于規(guī)范標(biāo)準(zhǔn)的布爾值。

“目的地是足夠溫暖的”的標(biāo)準(zhǔn)可能就是:

class TripRequiredTemperatureSpecification {
public function isSatisfiedBy($trip) {
$trip_temp = $trip->destination->getAvgTempByMonth(
date(‘m’, $trip->date));
return ($trip_temp >= $trip->traveler->min_temp);
}
}

下面是一些測(cè)試,用來(lái)檢驗(yàn)這個(gè)規(guī)范是如何工作的。

一個(gè)最初的個(gè)體測(cè)試事例提供了一些目的地來(lái)一起工作:

class TripSpecificationTestCase extends UnitTestCase {
protected $destinations = array();
function setup() {
$this->destinations = array(
‘Toronto’ => new Destination(
array(24, 25, 33, 43, 54, 63, 69, 69, 61, 50, 41, 29))
,’Cancun’ => new Destination(
array(74, 75, 78, 80, 82, 84, 84, 84, 83, 81, 78, 76))
);
}
}


(構(gòu)造這些目的地(Destination)需要在實(shí)例化的時(shí)候輸入一個(gè)包含每月平均溫度的數(shù)組。做為一個(gè)美國(guó)的作者,在這些例子中我選擇了華氏溫度。對(duì)應(yīng)的,Vicki期望的華氏溫度70度等價(jià)于攝氏溫度21度)

下一個(gè)測(cè)試構(gòu)建了一個(gè)旅行者(Traveler),并且設(shè)置了它的首選最低溫度和旅行日期同時(shí)也選擇了一個(gè)目的地。這最初的組合“最低溫度70度(華氏溫度),目的地多倫多(Toronto),日期二月中旬”會(huì)和期望的一樣,是不能通過(guò)的。

class TripSpecificationTestCase extends UnitTestCase {
// ...
function TestTripTooCold() {
$vicki = new Traveler;
$vicki->min_temp = 70;
$toronto = $this->destinations[‘Toronto’];
$trip = new Trip;
$trip->traveler = $vicki;
$trip->destination = $toronto;
$trip->date = mktime(0,0,0,2,11,2005);
$warm_enough_check = new TripRequiredTemperatureSpecification;
$this->assertFalse($warm_enough_check->isSatisfiedBy($trip));
}
}

但是,接下來(lái)的這個(gè)組合“70度,二月中旬,Cancun ”就會(huì)通過(guò),和我們期望的一樣。

class TripSpecificationTestCase extends UnitTestCase {
// ...
function TestTripWarmEnough() {
$vicki = new Traveler;
$vicki->min_temp = 70;
$cancun = $this->destinations[‘Cancun’];
$trip = new Trip;
$trip->traveler = $vicki;
$trip->destination = $cancun;
$trip->date = mktime(0,0,0,2,11,2005);
$warm_enough_check = new TripRequiredTemperatureSpecification;
$this->assertTrue($warm_enough_check->isSatisfiedBy($trip));
}
}

分享:《PHP設(shè)計(jì)模式介紹》第八章 迭代器模式
類(lèi)中的面向?qū)ο缶幊谭庋b應(yīng)用邏輯。類(lèi),就是實(shí)例化的對(duì)象,每個(gè)單獨(dú)的對(duì)象都有一個(gè)特定的身份和狀態(tài)。單獨(dú)的對(duì)象是一種組織代碼的有用方法,但通常你會(huì)處理一組對(duì)象或者集合。 屬性來(lái)自 SQL 查

共4頁(yè)上一頁(yè)1234下一頁(yè)
來(lái)源:模板無(wú)憂//所屬分類(lèi):PHP教程/更新時(shí)間:2008-08-22
相關(guān)PHP教程