適配器模式:將一個類的接口轉換成客戶但願的另外一個接口。適配器模式讓那些接口不兼容的類能夠一塊兒工做html
主要解決:主要解決在軟件系統中,經常要將一些"現存的對象"放到新的環境中,而新環境要求的接口是現對象不能知足的。android
什麼時候使用:設計模式
如何解決:繼承或依賴(推薦)。app
關鍵代碼:適配器繼承或依賴已有的對象,實現想要的目標接口。ide
適配器模式的別名爲包裝器(Wrapper)模式,它既能夠做爲類結構型模式,也能夠做爲對象結構型模式。在適配器模式定義中所說起的接口是指廣義的接口,它能夠表示一個方法或者方法的集合。函數
由圖可知適配器模式包含一下三個角色:post
Target (目標抽象類):目標抽象類定義客戶所需的接口,能夠是一個抽象類或接口,也能夠是具體類。在類適配器中,因爲C#語言不支持多重繼承,因此它只能是接口。this
Adapter (適配器類):它能夠調用另外一個接口,做爲一個轉換器,對 Adaptee 和 Target 進行適配。它是適配器模式的核心。url
Adaptee (適配者類):適配者即被適配的角色,它定義了一個已經存在的接口,這個接口須要適配,適配者類包好了客戶但願的業務方法。spa
例如美國的電壓是 110v,中國的電壓是220。當咱們到美國的時候,使用國產自帶的電器的時候,就須要將電壓轉爲220,才能使用。
下面咱們將上面的例子轉爲代碼。
/** * Traget角色 */ public interface Volt110 { int getVolt110(); } /** * adaptee角色,須要被轉換的對象 */ public class Volt220 { public int getVolt220() { return 220; } } /** * Adapter 角色,將 220V 的電壓轉換爲 110V 的電壓 */ public class VoltAdapter extends Volt220 implements Volt110 { @Override public int getVolt110() { return 110; } }
Target 角色給出了須要的目標接口,而 Adaptee 類則是須要被轉換的對象。Adapter 則是將 Volt220 轉換成 Target 的接口。對應的 Target 的目標是要獲取 110V 的輸出電壓,而 Adaptee 正常輸出電壓是 220V,此時就須要電源適配器類將 220V 的電壓轉換爲 110V 電壓,解決接口不兼容的問題。
對於類適配器模式,adpter 須要繼承被轉化者對象,同時也要實現適配目標的接口,這樣才能將自身轉爲目標。
public class Test { public static void main() { VoltAdapter adapter = new VoltAdapter(); Log.d("輸出電壓", "" + adapter.getVolt110()); } }
與類適配器有點區別的是,這裏使用了代理模式來輸出220v的電壓。
/** * Traget角色 */ public interface Volt110 { int getVolt110(); } /** * adaptee角色,須要被轉換的對象 */ public class Volt220 { public int getVolt220() { return 220; } } /** * Adapter 角色,將 220V 的電壓轉換爲 110V 的電壓 */ public class VoltAdapter implements Volt110 { Volt220 mVolt220; public VoltAdapter(Volt220 adaptee){ this.mVolt220 = adaptee; } public int getVolt220() { return mVolt220.getVolt220(); } @Override public int () { return 110; } }
使用方式以下:
public class Test { public static void main() { VoltAdapter adapter = new VoltAdapter(new Volt220()); Log.d("輸出電壓", "" + adapter.getVolt110()); } }
這種實現方式直接將要適配的對象傳遞到 Adapter 中,使用組合的形式實現接口兼容的效果。這比類適配器方式更爲靈活,它的另外一個好處是被適配對象中的方法不會暴露出來,而類適配器因爲繼承了被適配器對象,所以,被適配對象類的函數在 Adapter 類中也都含有,這使得 Adapter 類出現一些奇怪的接口,用戶使用成本較高。所以,對象適配器模式更加靈活、使用。
優勢:
將目標類和適配者類解耦,經過引入一個適配器類來重用現有的適配者類,無需修改原有結構。
增長了類的透明性和複用性,將具體的業務實現過程封裝在適配者類中,對於客戶端類而言是透明的,並且提升了適配者的複用性,同一適配者類能夠在多個不一樣的系統中複用。
靈活性和擴展性都很是好,經過使用配置文件,能夠很方便的更換適配器,也能夠在不修改原有代碼的基礎上 增長新的適配器,徹底複合開閉原則。
缺點:
一次最多隻能適配一個適配者類,不能同時適配多個適配者。
適配者類不能爲最終類,在C#中不能爲sealed類
目標抽象類只能爲接口,不能爲類,其使用有必定的侷限性。
美國電器 110V,中國 220V,就要有一個適配器將 110V 轉化爲 220V。
JAVA JDK 1.1 提供了 Enumeration 接口,而在 1.2 中提供了 Iterator 接口,想要使用 1.2 的 JDK,則要將之前系統的 Enumeration 接口轉化爲 Iterator 接口,這時就須要適配器模式。
在 LINUX 上運行 WINDOWS 程序。
JAVA 中的 jdbc。
參考文獻