午夜剧场伦理_日本一道高清_国产又黄又硬_91黄色网战_女同久久另类69精品国产_妹妹的朋友在线

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

PHP設(shè)計(jì)模式(五)適配器模式Adapter實(shí)例詳解【結(jié)構(gòu)型】

瀏覽:204日期:2022-09-10 14:59:22

本文實(shí)例講述了PHP設(shè)計(jì)模式:適配器模式Adapter。分享給大家供大家參考,具體如下:

1. 概述:

接口的改變,是一個(gè)需要程序員們必須(雖然很不情愿)接受和處理的普遍問(wèn)題。程序提供者們修改他們的代碼;系統(tǒng)庫(kù)被修正;各種程序語(yǔ)言以及相關(guān)庫(kù)的發(fā)展和進(jìn)化。

例子1:iphone4,你即可以使用UBS接口連接電腦來(lái)充電,假如只有iphone沒(méi)有電腦,怎么辦呢?蘋(píng)果提供了iphone電源適配器。可以使用這個(gè)電源適配器充電。這個(gè)iphone的電源適配器就是類(lèi)似我們說(shuō)的適配器模式。(電源適配器就是把電源變成需要的電壓,也就是適配器的作用是使得一個(gè)東西適合另外一個(gè)東西。)

例子2:最典型的例子就是很多功能手機(jī),每一種機(jī)型都自帶有從電器,有一天自帶充電器壞了,而且市場(chǎng)沒(méi)有這類(lèi)型充電器可買(mǎi)了。怎么辦?萬(wàn)能充電器就可以解決。這個(gè)萬(wàn)能充電器就是適配器。

2. 問(wèn)題

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

3. 解決方案

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

適配器模式(Adapter Pattern),把一個(gè)類(lèi)的接口變換成客戶(hù)端所期待的另一種接口, Adapter模式使原本因接口不匹配(或者不兼容)而無(wú)法在一起工作的兩個(gè)類(lèi)能夠在一起工作。又稱(chēng)為轉(zhuǎn)換器模式、變壓器模式、包裝(Wrapper)器模式(把已有的一些類(lèi)包裝起來(lái),使之能有滿足需要的接口)。 考慮一下當(dāng)(不是假設(shè)!)一個(gè)第三方庫(kù)的API改變將會(huì)發(fā)生什么。過(guò)去你只能是咬緊牙關(guān)修改所有的客戶(hù)代碼,而情況往往還不那么簡(jiǎn)單。你可能正從事一項(xiàng)新的項(xiàng)目,它要用到新版本的庫(kù)所帶來(lái)的特性,但你已經(jīng)擁有許多舊的應(yīng)用程序,并且它們與以前舊版本的庫(kù)交互運(yùn)行地很好。你將無(wú)法證明這些新特性的利用價(jià)值,如果這次升級(jí)意味著將要涉及到其它應(yīng)用程序的客戶(hù)代碼。

4. 分類(lèi)

共有兩類(lèi)適配器模式:1.類(lèi)的適配器模式(采用繼承實(shí)現(xiàn))2.對(duì)象適配器(采用對(duì)象組合方式實(shí)現(xiàn))

1)類(lèi)適配器模式 ——適配器繼承自已實(shí)現(xiàn)的類(lèi)(一般多重繼承)。

Adapter與Adaptee是繼承關(guān)系

1、用一個(gè)具體的Adapter類(lèi)和Target進(jìn)行匹配。結(jié)果是當(dāng)我們想要一個(gè)匹配一個(gè)類(lèi)以及所有它的子類(lèi)時(shí),類(lèi)Adapter將不能勝任工作2、使得Adapter可以重定義Adaptee的部分行為,因?yàn)锳dapter是Adaptee的一個(gè)子集3、僅僅引入一個(gè)對(duì)象,并不需要額外的指針以間接取得adaptee2)對(duì)象適配器模式—— 適配器容納一個(gè)它包裹的類(lèi)的實(shí)例。在這種情況下,適配器調(diào)用被包裹對(duì)象的物理實(shí)體。

Adapter與Adaptee是委托關(guān)系

1、允許一個(gè)Adapter與多個(gè)Adaptee同時(shí)工作。Adapter也可以一次給所有的Adaptee添加功能2、使用重定義Adaptee的行為比較困難無(wú)論哪種適配器,它的宗旨都是:保留現(xiàn)有類(lèi)所提供的服務(wù),向客戶(hù)提供接口,以滿足客戶(hù)的期望。即在不改變?cè)邢到y(tǒng)的基礎(chǔ)上,提供新的接口服務(wù)。

5. 適用性

以下情況使用Adapter模式:

1 • 你想使用一個(gè)已經(jīng)存在的類(lèi),而它的接口不符合你的需求。2 • 你想創(chuàng)建一個(gè)可以復(fù)用的類(lèi),該類(lèi)可以與其他不相關(guān)的類(lèi)或不可預(yù)見(jiàn)的類(lèi)(即那些接口可能不一定兼容的類(lèi))協(xié)同工作。3 •(僅適用于對(duì)象Adapter)你想使用一些已經(jīng)存在的子類(lèi),但是不可能對(duì)每一個(gè)都進(jìn)行子類(lèi)化以匹配它們的接口。對(duì)象適配器可以適配它的父類(lèi)接口。即僅僅引入一個(gè)對(duì)象,并不需要額外的指針以間接取得adaptee。

6. 結(jié)構(gòu)

類(lèi)適配器使用多重繼承對(duì)一個(gè)接口與另一個(gè)接口進(jìn)行匹配,如下圖所示:

PHP設(shè)計(jì)模式(五)適配器模式Adapter實(shí)例詳解【結(jié)構(gòu)型】

對(duì)象匹配器依賴(lài)于對(duì)象組合,如下圖所示:

PHP設(shè)計(jì)模式(五)適配器模式Adapter實(shí)例詳解【結(jié)構(gòu)型】

7. 構(gòu)建模式的組成

•目標(biāo)角色(Target):— 定義Client使用的與特定領(lǐng)域相關(guān)的接口。• 客戶(hù)角色(Client):與符合Target接口的對(duì)象協(xié)同。• 被適配橘色(Adaptee):定義一個(gè)已經(jīng)存在并已經(jīng)使用的接口,這個(gè)接口需要適配。• 適配器角色(Adapte) :適配器模式的核心。它將對(duì)被適配Adaptee角色已有的接口轉(zhuǎn)換為目標(biāo)角色Target匹配的接口。對(duì)Adaptee的接口與Target接口進(jìn)行適配.

8. 效果

類(lèi)適配器和對(duì)象適配器有不同的權(quán)衡。

類(lèi)適配器

• 用一個(gè)具體的Adapter類(lèi)對(duì)Adaptee和Target進(jìn)行匹配。結(jié)果是當(dāng)我們想要匹配一個(gè)類(lèi)以及所有它的子類(lèi)時(shí),類(lèi)Adapter將不能勝任工作。• 使得Adapter可以重定義Adaptee的部分行為,因?yàn)锳dapter是Adaptee的一個(gè)子類(lèi)。• 僅僅引入了一個(gè)對(duì)象,并不需要額外的指針以間接得到 Adaptee。

對(duì)象適配器則

• 允許一個(gè)Adapter與多個(gè)Adaptee—即Adaptee本身以及它的所有子類(lèi)(如果有子類(lèi)的話)—同時(shí)工作。Adapter也可以一次給所有的Adaptee添加功能。• 使得重定義Adaptee的行為比較困難。這就需要生成Adaptee的子類(lèi)并且使得Adapter引用這個(gè)子類(lèi)而不是引用Adaptee本身。

使用Adapter模式時(shí)需要考慮的其他一些因素有:

1) Adapter的匹配程度 對(duì)Adaptee的接口與Target的接口進(jìn)行匹配的工作量各個(gè)Adapter可能不一樣。工作范圍可能是,從簡(jiǎn)單的接口轉(zhuǎn)換(例如改變操作名 )到支持完全不同的操作集合。Adapter的工作量取決于Target接口與Adaptee接口的相似程度2) 可插入的Adapter 當(dāng)其他的類(lèi)使用一個(gè)類(lèi)時(shí),如果所需的假定條件越少,這個(gè)類(lèi)就更具可復(fù)用性。如果將接口匹配構(gòu)建為一個(gè)類(lèi),就不需要假定對(duì)其他的類(lèi)可見(jiàn)的是一個(gè)相同的接口。也就是說(shuō),接口匹配使得我們可以將自己的類(lèi)加入到一些現(xiàn)有的系統(tǒng)中去,而這些系統(tǒng)對(duì)這個(gè)類(lèi)的接口可能會(huì)有所不同。 3) 使用雙向適配器提供透明操作 使用適配器的一個(gè)潛在問(wèn)題是,它們不對(duì)所有的客戶(hù)都透明。被適配的對(duì)象不再兼容 Adaptee的接口,因此并不是所有 Adaptee對(duì)象可以被使用的地方它都可以被使用。雙向適配器提供了這樣的透明性。在兩個(gè)不同的客戶(hù)需要用不同的方式查看同一個(gè)對(duì)象時(shí),雙向適配器尤其有用。

9. 實(shí)現(xiàn)

類(lèi)適配器使用的是繼承

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

<?php/** * 類(lèi)適配器模式 * @author guisu * */ /** * 目標(biāo)角色 * @version 1.0 */class Target { /** * 這個(gè)方法將來(lái)有可能改進(jìn) */ public function hello(){ echo ’Hello ’; } /** * 目標(biāo)點(diǎn) */ public function world(){ echo ’world’; }} /** * Client 程序 * */class Client { /** * Main program. */ public static function main() { $Target = new Target(); $Target->hello(); $Target->world(); } }Client::main();?>

我們Target已經(jīng)明確指出hello()方法會(huì)在未來(lái)的版本中改進(jìn),甚至不被支持或者淘汰。接下來(lái),現(xiàn)在假設(shè)第二版的Target已經(jīng)發(fā)布。一個(gè)全新的greet()方法代替了hello()。

<?php/** * 類(lèi)適配器模式 * @author guisu * */ /** * 目標(biāo)角色 * @version 2.0 */class Target { /** * 這個(gè)方法將來(lái)有可能繼續(xù)改進(jìn) */ public function greet(){ echo ’Greet ’; } /** * 目標(biāo)點(diǎn) */ public function world(){ echo ’world’; }}

如果我們繼續(xù)使用原來(lái)的client代碼,肯定會(huì)報(bào)錯(cuò),找不到hello方法。

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

類(lèi)適配器使用的是繼承:

<?php/** * 類(lèi)適配器模式 * @author guisu * */ /** * 目標(biāo)角色 * @version 2.0 */interface Target { /** * 源類(lèi)的方法:這個(gè)方法將來(lái)有可能繼續(xù)改進(jìn) */ public function hello(); /** * 目標(biāo)點(diǎn) */ public function world();} /** * 源角色:被適配的角色 */class Adaptee { /** * 源類(lèi)含有的方法 */ public function world() { echo ’ world <br />’; } /** * 加入新的方法 */ public function greet() { echo ’ Greet ’; }} /** * 類(lèi)適配器角色 */class Adapter extends Adaptee implements Target { /** * 源類(lèi)中沒(méi)有world方法,在此補(bǔ)充 */ public function hello() { parent::greet(); } }/** * 客戶(hù)端程序 * */class Client { /** * Main program. */ public static function main() { $adapter = new Adapter(); $adapter->hello(); $adapter->world(); }}Client::main();?>

對(duì)象適配器使用的是委派

<?php/** * 類(lèi)適配器模式 * @author guisu * */ /** * 目標(biāo)角色 * @version 2.0 */interface Target { /** * 源類(lèi)的方法:這個(gè)方法將來(lái)有可能繼續(xù)改進(jìn) */ public function hello(); /** * 目標(biāo)點(diǎn) */ public function world();} /** * 源角色:被適配的角色 */class Adaptee { /** * 源類(lèi)含有的方法 */ public function world() { echo ’ world <br />’; } /** * 加入新的方法 */ public function greet() { echo ’ Greet ’; }} /** * 類(lèi)適配器角色 */class Adapter implements Target { private $_adaptee; /** * construct * * @param Adaptee $adaptee */ public function __construct(Adaptee $adaptee) { $this->_adaptee = $adaptee; } /** * 源類(lèi)中沒(méi)有world方法,在此補(bǔ)充 */ public function hello() { $this->_adaptee->greet(); } /** * 源類(lèi)中沒(méi)有world方法,在此補(bǔ)充 */ public function world() { $this->_adaptee->world(); }}/** * 客戶(hù)端程序 * */class Client { /** * Main program. */ public static function main() { $adaptee = new Adaptee(); $adapter = new Adapter($adaptee); $adapter->hello(); $adapter->world(); }}Client::main();?>

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

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

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

10.適配器模式與其它相關(guān)模式

橋梁模式(bridge模式):橋梁模式與對(duì)象適配器類(lèi)似,但是橋梁模式的出發(fā)點(diǎn)不同:橋梁模式目的是將接口部分和實(shí)現(xiàn)部分分離,從而對(duì)它們可以較為容易也相對(duì)獨(dú)立的加以改變。而對(duì)象適配器模式則意味著改變一個(gè)已有對(duì)象的接口

裝飾器模式(decorator模式):裝飾模式增強(qiáng)了其他對(duì)象的功能而同時(shí)又不改變它的接口。因此裝飾模式對(duì)應(yīng)用的透明性比適配器更好。結(jié)果是decorator模式支持遞歸組合,而純粹使用適配器是不可能實(shí)現(xiàn)這一點(diǎn)的。

Facade(外觀模式):適配器模式的重點(diǎn)是改變一個(gè)單獨(dú)類(lèi)的API。Facade的目的是給由許多對(duì)象構(gòu)成的整個(gè)子系統(tǒng),提供更為簡(jiǎn)潔的接口。而適配器模式就是封裝一個(gè)單獨(dú)類(lèi),適配器模式經(jīng)常用在需要第三方API協(xié)同工作的場(chǎng)合,設(shè)法把你的代碼與第三方庫(kù)隔離開(kāi)來(lái)。

適配器模式與外觀模式都是對(duì)現(xiàn)相存系統(tǒng)的封裝。但這兩種模式的意圖完全不同,前者使現(xiàn)存系統(tǒng)與正在設(shè)計(jì)的系統(tǒng)協(xié)同工作而后者則為現(xiàn)存系統(tǒng)提供一個(gè)更為方便的訪問(wèn)接口。簡(jiǎn)單地說(shuō),適配器模式為事后設(shè)計(jì),而外觀模式則必須事前設(shè)計(jì),因?yàn)橄到y(tǒng)依靠于外觀。總之,適配器模式?jīng)]有引入新的接口,而外觀模式則定義了一個(gè)全新的接口。

代理模式(Proxy )在不改變它的接口的條件下,為另一個(gè)對(duì)象定義了一個(gè)代理。

裝飾者模式,適配器模式,外觀模式三者之間的區(qū)別:

裝飾者模式的話,它并不會(huì)改變接口,而是將一個(gè)一個(gè)的接口進(jìn)行裝飾,也就是添加新的功能。

適配器模式是將一個(gè)接口通過(guò)適配來(lái)間接轉(zhuǎn)換為另一個(gè)接口。

外觀模式的話,其主要是提供一個(gè)整潔的一致的接口給客戶(hù)端。

更多關(guān)于PHP相關(guān)內(nèi)容感興趣的讀者可查看本站專(zhuān)題:《php面向?qū)ο蟪绦蛟O(shè)計(jì)入門(mén)教程》、《PHP數(shù)組(Array)操作技巧大全》、《PHP基本語(yǔ)法入門(mén)教程》、《PHP運(yùn)算與運(yùn)算符用法總結(jié)》、《php字符串(string)用法總結(jié)》、《php+mysql數(shù)據(jù)庫(kù)操作入門(mén)教程》及《php常見(jiàn)數(shù)據(jù)庫(kù)操作技巧匯總》

希望本文所述對(duì)大家PHP程序設(shè)計(jì)有所幫助。

標(biāo)簽: PHP
相關(guān)文章:
主站蜘蛛池模板: 久久精品成人一区二区三区蜜臀 | 国产精品美女一区 | 国产激情综合 | av伦理在线 | 一二三不卡视频 | 日韩中文字幕一区二区 | 色网址在线 | 91精品一区 | 午夜激情视频网站 | 超碰在线99 | 成人av动漫在线观看 | 天天综合天天 | 激情的少妇| 亚洲涩色 | 色视频在线观看 | 在线看黄网 | 欧美一级生活片 | 老牛嫩草二区三区观影体验 | 免费啪啪小视频 | 国产哺乳奶水91在线播放 | 91狠狠干| 成人免费影院 | 在线视频观看你懂的 | 久久久亚洲天堂 | 中文有码在线播放 | 欧美 日韩 精品 | 艳母免费在线观看 | 国产视频成人 | 亚洲一区二区影院 | 免费成人黄色片 | 亚洲精品一区二三区 | 操穴av | 中文字幕观看在线 | 日韩一级片在线播放 | 九九热久久免费视频 | 91动态图 | 亚洲区一区二区三 | 福利社午夜影院 | 欧美成人做爰大片免费看黄石 | 成年人黄色一级片 | 久久一区二区视频 |