
今天我來全面總結(jié)一下Android開發(fā)中最常用的設(shè)計(jì)模式 - 適配器模式。
其他設(shè)計(jì)模式介紹 1分鐘全面了解“設(shè)計(jì)模式” 單例模式(Singleton) - 最易懂的設(shè)計(jì)模式解析 簡(jiǎn)單工廠模式(SimpleFactoryPattern)- 最易懂的設(shè)計(jì)模式解析 工廠方法模式(Factory Method)- 最易懂的設(shè)計(jì)模式解析 抽象工廠模式(Abstract Factory)- 最易懂的設(shè)計(jì)模式解析 策略模式(Strategy Pattern)- 最易懂的設(shè)計(jì)模式解析 適配器模式(Adapter Pattern)- 最易懂的設(shè)計(jì)模式解析 代理模式(PRoxy Pattern)- 最易懂的設(shè)計(jì)模式解析 模板方法模式(Template Method) - 最易懂的設(shè)計(jì)模式解析 建造者模式(Builder Pattern)- 最易懂的設(shè)計(jì)模式解析 外觀模式(Facade Pattern) - 最易懂的設(shè)計(jì)模式解析

適配器模式,即定義一個(gè)包裝類,用于包裝不兼容接口的對(duì)象
包裝類 = 適配器Adapter; 被包裝對(duì)象 = 適配者Adaptee = 被適配的類
把一個(gè)類的接口變換成客戶端所期待的另一種接口,從而使原本接口不匹配而無法一起工作的兩個(gè)類能夠在一起工作。
適配器模式的形式分為:類的適配器模式和對(duì)象的適配器模式
原本由于接口不兼容而不能一起工作的那些類可以在一起工作。
類的適配器模式是把適配的類的API轉(zhuǎn)換成為目標(biāo)類的API。
2.1.1 UML類圖 & 組成
在上圖中可以看出:
Adapter與Adaptee是繼承關(guān)系,這決定了這個(gè)適配器模式是類的
2.1.2 使用步驟(代碼解析)
步驟1: 創(chuàng)建Target接口;
public interface Target { //這是源類Adapteee沒有的方法 public void Request(); }步驟2: 創(chuàng)建源類(Adaptee) ;
public class Adaptee { public void SpecificRequest(){ }}步驟3: 創(chuàng)建適配器類(Adapter)
//適配器Adapter繼承自Adaptee,同時(shí)又實(shí)現(xiàn)了目標(biāo)(Target)接口。public class Adapter extends Adaptee implements Target { //目標(biāo)接口要求調(diào)用Request()這個(gè)方法名,但源類Adaptee沒有方法Request() //因此適配器補(bǔ)充上這個(gè)方法名 //但實(shí)際上Request()只是調(diào)用源類Adaptee的SpecificRequest()方法的內(nèi)容 //所以適配器只是將SpecificRequest()方法作了一層封裝,封裝成Target可以調(diào)用的Request()而已 @Override public void Request() { this.SpecificRequest(); }}步驟4: 定義具體使用目標(biāo)類,并通過Adapter類調(diào)用所需要的方法從而實(shí)現(xiàn)目標(biāo)
public class AdapterPattern { public static void main(String[] args){ Target mAdapter = new Adapter(); mAdapter.Request(); }}2.1.3 實(shí)例講解 接下來我用一個(gè)實(shí)例來對(duì)類的適配器模式進(jìn)行更深一步的介紹。 a. 實(shí)例概況
背景:小成買了一個(gè)進(jìn)口的電視機(jī)沖突:進(jìn)口電視機(jī)要求電壓(110V)與國(guó)內(nèi)插頭標(biāo)準(zhǔn)輸出電壓(220V)不兼容解決方案:設(shè)置一個(gè)適配器將插頭輸出的220V轉(zhuǎn)變成110V即適配器模式中的類的適配器模式
b. 使用步驟 步驟1: 創(chuàng)建Target接口(期待得到的插頭):能輸出110V(將220V轉(zhuǎn)換成110V)
public interface Target { //將220V轉(zhuǎn)換輸出110V(原有插頭(Adaptee)沒有的) public void Convert_110v();}步驟2: 創(chuàng)建源類(原有的插頭) ;
class PowerPort220V{//原有插頭只能輸出220V public void Output_220v(){ }}步驟3: 創(chuàng)建適配器類(Adapter)
class Adapter220V extends PowerPort220V implements Target{ //期待的插頭要求調(diào)用Convert_110v(),但原有插頭沒有 //因此適配器補(bǔ)充上這個(gè)方法名 //但實(shí)際上Convert_110v()只是調(diào)用原有插頭的Output_220v()方法的內(nèi)容 //所以適配器只是將Output_220v()作了一層封裝,封裝成Target可以調(diào)用的Convert_110v()而已 @Override public void Convert_110v(){ this.Output_220v; }}步驟4: 定義具體使用目標(biāo)類,并通過Adapter類調(diào)用所需要的方法從而實(shí)現(xiàn)目標(biāo)(不需要通過原有插頭)
//進(jìn)口機(jī)器類class ImportedMachine { @Override public void Work() { System.out.println("進(jìn)口機(jī)器正常運(yùn)行"); }}//通過Adapter類從而調(diào)用所需要的方法public class AdapterPattern { public static void main(String[] args){ Target mAdapter220V = new Adapter220V(); ImportedMachine mImportedMachine = new ImportedMachine(); //用戶拿著進(jìn)口機(jī)器插上適配器(調(diào)用Convert_110v()方法) //再將適配器插上原有插頭(Convert_110v()方法內(nèi)部調(diào)用Output_220v()方法輸出220V) //適配器只是個(gè)外殼,對(duì)外提供110V,但本質(zhì)還是220V進(jìn)行供電 mAdapter220V.Convert_110v(); mImportedMachine.Work(); }}與類的適配器模式相同,對(duì)象的適配器模式也是把適配的類的API轉(zhuǎn)換成為目標(biāo)類的API。
與類的適配器模式不同的是,對(duì)象的適配器模式不是使用繼承關(guān)系連接到Adaptee類,而是使用委派關(guān)系連接到Adaptee類。
2.2.1 UML類圖

在上圖中可以看出:
沖突:Target期待調(diào)用Request方法,而Adaptee并沒有(這就是所謂的不兼容了)。解決方案:為使Target能夠使用Adaptee類里的SpecificRequest方法,故提供一個(gè)中間環(huán)節(jié)Adapter類(包裝了一個(gè)Adaptee的實(shí)例),把Adaptee的API與Target的API銜接起來(適配)。Adapter與Adaptee是委派關(guān)系,這決定了適配器模式是對(duì)象的。 2.2.2 使用步驟(代碼解析)
步驟1: 創(chuàng)建Target接口;
public interface Target { //這是源類Adapteee沒有的方法 public void Request(); }步驟2: 創(chuàng)建源類(Adaptee) ;
public class Adaptee { public void SpecificRequest(){ }}步驟3: 創(chuàng)建適配器類(Adapter)(不適用繼承而是委派)
class Adapter implements Target{ // 直接關(guān)聯(lián)被適配類 private Adaptee adaptee; // 可以通過構(gòu)造函數(shù)傳入具體需要適配的被適配類對(duì)象 public Adapter (Adaptee adaptee) { this.adaptee = adaptee; } @Override public void Request() { // 這里是使用委托的方式完成特殊功能 this.adaptee.SpecificRequest(); } }步驟4: 定義具體使用目標(biāo)類,并通過Adapter類調(diào)用所需要的方法從而實(shí)現(xiàn)目標(biāo)
public class AdapterPattern { public static void main(String[] args){ //需要先創(chuàng)建一個(gè)被適配類的對(duì)象作為參數(shù) Target mAdapter = new Adapter(new Adaptee()); mAdapter.Request(); }}在這里我就不再舉實(shí)例進(jìn)行講解了(詳情請(qǐng)看上面“進(jìn)口機(jī)器的插頭”),只是在適配類實(shí)現(xiàn)時(shí)將“繼承”改成“在內(nèi)部委派Adaptee類”而已
優(yōu)點(diǎn)
更好的復(fù)用性 系統(tǒng)需要使用現(xiàn)有的類,而此類的接口不符合系統(tǒng)的需要。那么通過適配器模式就可以讓這些功能得到更好的復(fù)用。透明、簡(jiǎn)單 客戶端可以調(diào)用同一接口,因而對(duì)客戶端來說是透明的。這樣做更簡(jiǎn)單 & 更直接更好的擴(kuò)展性 在實(shí)現(xiàn)適配器功能的時(shí)候,可以調(diào)用自己開發(fā)的功能,從而自然地?cái)U(kuò)展系統(tǒng)的功能。解耦性 將目標(biāo)類和適配者類解耦,通過引入一個(gè)適配器類重用現(xiàn)有的適配者類,而無需修改原有代碼符合開放-關(guān)閉原則 同一個(gè)適配器可以把適配者類和它的子類都適配到目標(biāo)接口;可以為不同的目標(biāo)接口實(shí)現(xiàn)不同的適配器,而不需要修改待適配類缺點(diǎn)
過多的使用適配器,會(huì)讓系統(tǒng)非常零亂,不易整體進(jìn)行把握優(yōu)點(diǎn)
使用方便,代碼簡(jiǎn)化 僅僅引入一個(gè)對(duì)象,并不需要額外的字段來引用Adaptee實(shí)例缺點(diǎn)
高耦合,靈活性低 使用對(duì)象繼承的方式,是靜態(tài)的定義方式優(yōu)點(diǎn)
靈活性高、低耦合 采用 “對(duì)象組合”的方式,是動(dòng)態(tài)組合方式缺點(diǎn)
使用復(fù)雜 需要引入對(duì)象實(shí)例特別是需要重新定義Adaptee行為時(shí)需要重新定義Adaptee的子類,并將適配器組合適配
靈活使用時(shí):選擇對(duì)象的適配器模式 類適配器使用對(duì)象繼承的方式,是靜態(tài)的定義方式;而對(duì)象適配器使用對(duì)象組合的方式,是動(dòng)態(tài)組合的方式。
需要同時(shí)配源類和其子類:選擇對(duì)象的適配器
對(duì)于類適配器,由于適配器直接繼承了Adaptee,使得適配器不能和Adaptee的子類一起工作,因?yàn)槔^承是靜態(tài)的關(guān)系,當(dāng)適配器繼承了Adaptee后,就不可能再去處理 Adaptee的子類了;對(duì)于對(duì)象適配器,一個(gè)適配器可以把多種不同的源適配到同一個(gè)目標(biāo)。換言之,同一個(gè)適配器可以把源類和它的子類都適配到目標(biāo)接口。因?yàn)閷?duì)象適配器采用的是對(duì)象組合的關(guān)系,只要對(duì)象類型正確,是不是子類都無所謂。需要重新定義Adaptee的部分行為:選擇類適配器
對(duì)于類適配器,適配器可以重定義Adaptee的部分行為,相當(dāng)于子類覆蓋父類的部分實(shí)現(xiàn)方法。對(duì)于對(duì)象適配器,要重定義Adaptee的行為比較困難,這種情況下,需要定義Adaptee的子類來實(shí)現(xiàn)重定義,然后讓適配器組合子類。雖然重定義Adaptee的行為比較困難,但是想要增加一些新的行為則方便的很,而且新增加的行為可同時(shí)適用于所有的源。僅僅希望使用方便時(shí):選擇類適配器
對(duì)于類適配器,僅僅引入了一個(gè)對(duì)象,并不需要額外的引用來間接得到Adaptee。對(duì)于對(duì)象適配器,需要額外的引用來間接得到Adaptee。建議盡量使用對(duì)象的適配器模式,多用合成/聚合、少用繼承。
當(dāng)然,具體問題具體分析,根據(jù)需要來選用合適的實(shí)現(xiàn)方式
本文主要對(duì)適配器模式進(jìn)行了全面介紹,接下來將介紹其他設(shè)計(jì)模式,有興趣可以繼續(xù)關(guān)注Carson_Ho的安卓開發(fā)筆記!!!!
相關(guān)文章閱讀 單例模式(Singleton) - 最易懂的設(shè)計(jì)模式解析 簡(jiǎn)單工廠模式(SimpleFactoryPattern)- 最易懂的設(shè)計(jì)模式解析 工廠方法模式(Factory Method)- 最易懂的設(shè)計(jì)模式解析 抽象工廠模式(Abstract Factory)- 最易懂的設(shè)計(jì)模式解析 策略模式(Strategy Pattern)- 最易懂的設(shè)計(jì)模式解析 適配器模式(Adapter Pattern)- 最易懂的設(shè)計(jì)模式解析 代理模式(Proxy Pattern)- 最易懂的設(shè)計(jì)模式解析 模板方法模式(Template Method) - 最易懂的設(shè)計(jì)模式解析 建造者模式(Builder Pattern)- 最易懂的設(shè)計(jì)模式解析 外觀模式(Facade Pattern) - 最易懂的設(shè)計(jì)模式解析
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注