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

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

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

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

接口的改變,是一個需要程序員們必須(雖然很不情愿)接受和處理的普遍問題。程序提供者們修改他們的代碼;系統(tǒng)庫被修正;各種程序語言以及相關(guān)庫的發(fā)展和進化。我孩子的無數(shù)玩具中有一個簡要地描述了這個兩難局面:你無法合理安排一個不得其所的人。

問題

你如何避免因外部庫的API改變而帶來的不便?假如你寫了一個庫,你能否提供一種方法允許你軟件的現(xiàn)有用戶進行完美地升級,即使你已經(jīng)改變了你的API?為了更好地適宜于你的需要,你應(yīng)該如何改變一個對象的接口?

解決方案

適配器(Adapter)模式為對象提供了一種完全不同的接口。你可以運用適配器(Adapter)來實現(xiàn)一個不同的類的常見接口,同時避免了因升級和拆解客戶代碼所引起的糾紛。

考慮一下當(dāng)(不是假設(shè)!)一個第三方庫的API改變將會發(fā)生什么。過去你只能是咬緊牙關(guān)修改所有的客戶代碼,而情況往往還不那么簡單。你可能正從事一項新的項目,它要用到新版本的庫所帶來的特性,但你已經(jīng)擁有許多舊的應(yīng)用程序,并且它們與以前舊版本的庫交互運行地很好。你將無法證明這些新特性的利用價值,如果這次升級意味著將要涉及到其它應(yīng)用程序的客戶代碼。

注:控制體模式

適配器(Adapter)模式是控制體模式的最新范例。一個適配器(Adapter)的結(jié)構(gòu)類似于代理服務(wù)器(Proxy)和修飾器(Decorator),而它們的不同之處在于,適配器(Adapter)的目的是改變封裝類的接口,代理服務(wù)器(Proxy)和修飾器(Decorator)則是保持接口不變。

樣本代碼

讓我們看看當(dāng)API改變時,如何保護應(yīng)用程序不受影響。

假設(shè)你費盡心思尋找合適的庫,最后終于找到了HwLib,一個(假設(shè)的)被設(shè)計用來發(fā)送信息的代碼集。

下面是HwLib類的源代碼:

// PHP4
/**
* the HwLib helps programmers everywhere write their first program
* @package HelloWorld
* @version 1
*/
class HwLib {
/**
* Say “Hello”
* @deprec this function is going away in the future
* @return string
*/
function hello() {
return ‘Hello ‘;
}
/**
* target audience
* @return string
*/
function world() {
return ‘World!’;
}
}

下面是庫運行的范例:

$hw =& new HwLib;
echo $hw->hello(), $hw->world();

HwLib有完備的說明文檔。在文檔中作者已經(jīng)明確指出hello()方法會在未來的版本中不被支持(甚至淘汰)。

接下來,現(xiàn)在假設(shè)第二版的HwLib已經(jīng)發(fā)布。一個全新的greet()方法代替了hello()。

下面是這個庫的新版本(注釋已被抽取掉):

// version 2
class HwLib {
function greet() {
return ‘Greetings and Salutations ‘;
}
unction world() {
return ‘World!’;
}
}

為了適應(yīng)HwLib的不同版本進行編碼,先進行一些基于第一版本HwLib接口的測試:

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

你同樣可以表明,對這個庫的簡單升級將造成此應(yīng)用程序的失效。

class AdapterTestCase extends UnitTestCase {
function TestOriginalAppWouldFail() {
$lib =& new HwLib; // now using HwLib version 2
$this->assertFalse(method_exists($lib, ‘hello’));
}
}

(這個測試以method_exists()為例證。如果你簡單地更換這個庫的第二版本并且以TestOriginalApp()的測試再次運行AdapterTestCase,PHP就會運行失敗,同時報告“致命錯誤:未定義的函數(shù):hello()”)

針對API“升級”的解決辦法就是創(chuàng)建一個適配器(Adapter)。

第一步是獲得第二版本HwLib的實例的一個引用,并且把它加入到你的Adapter類中。

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

這個范例展示了將這個實例傳遞給構(gòu)造函數(shù)的過程,你也可以運用Factory 或 Singleton ,或者其它適合你要求的創(chuàng)建模式,來創(chuàng)建一個新的實例。(通過前兩章,你應(yīng)該對HwLibV2ToV1Adapter的編寫用途很熟悉了)

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

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