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

《PHP設(shè)計(jì)模式介紹》第十三章 適配器模式(2)_PHP教程

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

推薦:《PHP設(shè)計(jì)模式介紹》第十二章 裝飾器模式
若你從事過(guò)面向?qū)ο蟮膒hp開(kāi)發(fā),即使很短的時(shí)間或者僅僅通過(guò)本書(shū)了解了一些,你會(huì)知道,你可以 通過(guò)繼承改變或者增加一個(gè)類的功能,這是所有面向?qū)ο笳Z(yǔ)言的一個(gè)基本特性。如果已經(jīng)存在的一個(gè)php

當(dāng)?shù)玫降诙姹綡wLib的時(shí)候,你如何使它在第一版本HwLib的實(shí)例中體現(xiàn)?

class HwLibV2ToV1Adapter {
var $libv2;
function HwLibV2ToV1Adapter (&$libv2) {
$this->libv2 =& $libv2;
}
function hello() {
return $this->libv2->greet();
}
function world() {
return $this->libv2->world();
}
}

HwLibV2ToV1Adapter::hello()方法代表了$libv2對(duì)象的greet()方法。

接著,你該如何在程序中使用它?

class AdapterTestCase extends UnitTestCase {
function TestOriginalAppWithAdapter() {
$lib =& new HwLibV2ToV1Adapter(new HwLib);
$this->assertEqual(
‘Greetings and Salutations World!’
,$lib->hello().$lib->world());
}
}

剛才的程序測(cè)試和現(xiàn)在的程序代碼都有一定程度的脆弱性。有沒(méi)有方法在長(zhǎng)久的使用中讓它們都更易于維護(hù)呢?當(dāng)然是有的!

回憶一下(第三章)Factory是如何提供一個(gè)更靈活的方法來(lái)創(chuàng)建類的實(shí)例的。為了更好地在將來(lái)檢驗(yàn)這些代碼,就從一個(gè)簡(jiǎn)單的Factory函數(shù)開(kāi)始:

function &HwLibInstance() {
return new HwLib;
}

為了測(cè)試Factory,直接調(diào)用它而不創(chuàng)建它的實(shí)例:

class AdapterTestCase extends UnitTestCase {
function TestAppWithFactory() {
$lib =& HwLibInstance();
$this->assertWantedPattern(
‘/\w World!$/’
,$lib->hello().$lib->world());
}
}

有兩個(gè)方面需要注意:Factory創(chuàng)建了對(duì)象,而用于確認(rèn)的assertEqual()函數(shù)被修改為更靈活的assertWantedPattern()。你現(xiàn)在可以用一個(gè)正則表達(dá)式來(lái)捕獲你在庫(kù)中所要查找的“核心”,但可能會(huì)使這個(gè)測(cè)試本身變得脆弱。

接下來(lái),升級(jí)HwLib庫(kù)。當(dāng)安裝了HwLib第二版,你就可以修改HwLibInstance()函數(shù)來(lái)適應(yīng)新的版本。

function &HwLibInstance($ver=false) {
switch ($ver) {
case ‘V2’:
return new HwLib;
default:
return new HwLibV2ToV1Adapter(new HwLib);
}
}

現(xiàn)在重新運(yùn)行AdapterTestCase。測(cè)試通過(guò)!(綠色進(jìn)度條正常。)因?yàn)樵嫉某绦驔](méi)有傳遞一個(gè)參數(shù),HwLibInstance會(huì)默認(rèn)返回封裝在HwLibV2toV1Adapter中的HwLib的一個(gè)實(shí)例。盡管如此,如果你編寫(xiě)了新的代碼,你可以傳遞進(jìn)一個(gè)“V2”的參數(shù)讓這個(gè)函數(shù)自動(dòng)選擇HwLib的新版本而不用去調(diào)整它。

以后,如果你選擇升級(jí)HwLib的第三版,應(yīng)該將Factory做如下的調(diào)整:

function &HwLibInstance($ver=false) {
switch ($ver) {
case ‘V3’:
return new HwLib;
case ‘V2’:
return new HwLibV3ToV2Adapter(new HwLib);
default:
return new HwLibV2ToV1Adapter(
new HwLibV3ToV2Adapter(new HwLib));
}
}

總結(jié)

如例中代碼所示,你可以運(yùn)用適配器(Adapter)模式來(lái)避免因外部庫(kù)改變所帶來(lái)的不便——倘若向上兼容。作為某個(gè)庫(kù)的開(kāi)發(fā)者,你應(yīng)該獨(dú)立編寫(xiě)適配器,使你的用戶更簡(jiǎn)便地使用新版本的庫(kù),而不用去修改他們現(xiàn)有的全部代碼。

GoF書(shū)中提出的適配器(Adapter)模式更傾向于運(yùn)用繼承而不是組成。這在強(qiáng)類型語(yǔ)言中是有利的,因?yàn)檫m配器(Adapter)事實(shí)上是一個(gè)目標(biāo)類的子類,因而能更好地與類中方法相結(jié)合。

下面是HwLib適配器運(yùn)用繼承的范例:

class HwLibGofAdapter extends HwLib { // extending version 2.0
function hello() {
return parent::greet();
}
}

world()方法沒(méi)有在類中提到,因?yàn)檫\(yùn)用了繼承,它已經(jīng)是子類的一部分。

class AdapterTestCase extends UnitTestCase {
function TestHwLibGofAdapter() {
$lib =& new HwLibGofAdapter;
$this->assertEqual(
‘Greetings and Salutations World!’
,$lib->hello().$lib->world());
}
}

為了更好的靈活性,我個(gè)人比較傾向于組成的方法(特別是在結(jié)合了依賴性倒置的情況下);盡管如此,繼承的方法提供兩種版本的接口,或許在你的實(shí)際運(yùn)用中反而是一個(gè)提高靈活性的關(guān)鍵。

?注:依賴性倒置原理

依賴性倒置原理(首先在http://www.objectmentor.com/resources/articles/dip.pdf中由Robert C. Martin提出)是一個(gè)面向?qū)ο缶幊痰臏?zhǔn)則,它表明:高層次的模塊不應(yīng)該依賴于低層次的模塊,而應(yīng)依賴于抽取。一個(gè)簡(jiǎn)單的與適配器(Adapter)模式相結(jié)合的依賴性倒置原理范例可以在以下地址中找到:

http://www.phplondon.org/wiki/DependencyInversion

適配器模式的重點(diǎn)是改變一個(gè)單獨(dú)類的API。有一個(gè)與之相關(guān)的設(shè)計(jì)模式(本書(shū)中沒(méi)有涵蓋),稱作正面(Facade)模式。正面(Facade)的目的是給由許多對(duì)象構(gòu)成的整個(gè)子系統(tǒng),提供更為簡(jiǎn)潔的接口——反過(guò)來(lái)就是封裝一個(gè)單獨(dú)類——可能是一個(gè)值得研究的模式,如果你正設(shè)法把你的代碼與第三方庫(kù)隔離開(kāi)來(lái)的話。

分享:《PHP設(shè)計(jì)模式介紹》第十一章 代理模式
因?yàn)槟硞(gè)對(duì)象消耗太多資源,而且你的代碼并不是每個(gè)邏輯路徑都需要此對(duì)象, 你曾有過(guò)延遲創(chuàng)建對(duì)象的想法嗎 ( if和else就是不同的兩條邏輯路徑) ? 你有想過(guò)限制訪問(wèn)某個(gè)對(duì)象,也就是說(shuō),提供一組方法

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