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

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

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