java適配器模式
1、概述
什么是適配器模式?
適配器模式是一種結構型設計模式。適配器模式就是:把一個類的接口變換成客戶端所期待的另一種接口,從而使原本因接口不匹配而無法在一起工作的兩個類能夠在一起工作。
用電器來打個比喻:有一個電器的插頭是三腳的,而現有的插座是兩孔的,要使插頭插上插座,我們需要一個插頭轉換器,這個轉換器即是適配器。
適配器模式涉及3個角色:
- 源(Adaptee):需要被適配的對象或類型,相當於插頭。
- 適配器(Adapter):連接目標和源的中間對象,相當於插頭轉換器。
- 目標(Target):期待得到的目標,相當於插座。
2、適配器模式UML圖
圖片來自網絡
通過上面UML圖可以知道,客戶端期待的接口或者對象通過適配器的轉換得到了滿足,Adapter通過內部包裝Adaptee對象把源對象轉換成客戶端期待的對象。
3、適配器模式分類
適配器模式包括3種形式:
- 類適配器模式:類適配器使用的是繼承的方式,一般來說無法對其子類進行適配
- 對象適配器模式:對象適配器使用的是組合的方式,子孫類都可以被適配。另外,對象適配器對於增加一些新行為非常方便,而且新增加的行為同時適用於所有的源。
- 接口適配器模式(又稱缺省適配器模式):接口適配器模式(缺省適配模式)基本思想是,為一個接口提供缺省實現,這樣子類可以從這個缺省實現進行擴展,而不必從原有接口進行擴展。
可以說對象適配器模式是另外6種結構型設計模式的起源(圖片源自網絡)。
4、三種適配器模式詳解
適配器模式的三種實現方式及代碼實例詳解,用電器來打個比喻:有一個電器的插頭是兩腳的,而現有的插座是三孔的,要使插頭插上插座,我們需要一個插頭轉換器,這個轉換器即是適配器。
圖片源自網絡
4.1、類適配器模式
類適配器使用的是繼承的方式,一般來說無法對其子類進行適配,請看代碼實例
1.首先我們有一個要被適配的類
/** * 源(相當於兩腳插頭,也就是被適配的類) * @author ningbeibei */ public class Adaptee { public void adapteeMethod() { System.out.println("兩腳插頭,被適配的類...."); } }
2.定義一個目標接口
/** * 目標(客戶所期待的類,可以是一個接口抽象類具體的類) * 相當於三孔插板 * @author ningbeibei */ public interface Target { void targetMethod(); }
3.定義適配器類
定義適配器類通過繼承 Adaptee 和實現 Target 接口關聯起來,
/** * 類適配器模式(相當於轉換器) * 通過Adapter類把Adaptee類與Target接口銜接起來 * @author ningbeibei */ public class Adapter extends Adaptee implements Target { @Override public void targetMethod() { //操作處理 adapteeMethod(); //操作處理 } }
4.測試代碼
/** * 適配器模式測試類 * @author ningbeibei */ public class test { public static void main(String[] args) { //類適配器模式 Adapter adapter = new Adapter(); adapter.targetMethod(); } }
5.運行結果
4.2、對象適配器模式
對象適配器使用的是組合的方式,它把源類作為屬性放入適配器類中,請看代碼實例
1.定義被適配的類
/** * 源(相當於兩腳插頭,也就是被適配的類) * @author ningbeibei */ public class Adaptee { public void adapteeMethod() { System.out.println("兩腳插頭,被適配的類...."); } }
2.定義目標接口
/** * 目標(客戶所期待的類,可以是一個接口抽象類具體的類) * 相當於三孔插板 * @author ningbeibei */ public interface Target { void targetMethod(); }
3.定義適配器類(類似於轉換器)
注意:通過持有Adaptee屬性建立與Target接口聯系
/** * 對象適配器模式(相當於轉換器) * 通過持有Adaptee屬性建立與Target接口聯系 * @author ningbeibei */ public class Adapter implements Target { //添加屬性 private Adaptee adaptee; public Adapter (Adaptee adaptee) { this.adaptee = adaptee; } @Override public void targetMethod() { //操作處理 adaptee.adapteeMethod(); //操作處理 } }
4.測試類
/** * 適配器模式測試類 * @author ningbeibei */ public class test { public static void main(String[] args) { //對象適配器模式 Adapter adapter = new Adapter(new Adaptee()); adapter.targetMethod(); } }
5.結果輸出
4.3、接口適配器模式(缺省適配模式)
接口適配器模式又稱缺省模式,這種模式通過抽象類對接口進行實現,在抽象類種對接口進行默認實現。請看下面代碼示例
1.定義頂層接口
/** * 定義頂層接口 * @author ningbeibei */ public interface Target { void targetMethod(); void targetMethod1(); void targetMethod2(); }
2.定義抽象類 AbstrctAdapter 並實現 Target 接口
/** * 接口適配器模式 * 定義抽象類並實現Target接口 * @author ningbeibei */ public abstract class AbstrctAdapter implements Target { //默認實現方法 public void targetMethod() { System.out.println("默認實現"); }; //需要子類必須實現的方法 public abstract void targetMethod1(); //需要子類重寫這個方法 public void targetMethod2() { System.out.println("默認實現2"); }; }
3.定義Adapter類並繼承AbstrctAdapte抽象類
通過接口和抽象類的結合,避免了在實現接口的子類中出現大量的“無意義”實現,這個“無意義”實現,被緩沖到了抽象類中,完美展現了代碼復用(可以把抽象類理解成接口和實現類之間的緩沖)
/** * 通過繼承AbstrctAdapter抽象類 * 實現它的抽象方法和重寫方法 * 這種方式是通過抽象類緩沖接口中那些我們不想實現的空方法 * @author ningbeibei */ public class Adapter extends AbstrctAdapter { @Override public void targetMethod1() { System.out.println("子類必須實現"); } public void targetMethod2() { System.out.println("重寫實現2"); }; }
4.測試類
/** * 缺省模式 * @author ningbeibei */ public class test { public static void main(String[] args) { Adapter adapter = new Adapter(); adapter.targetMethod(); adapter.targetMethod1(); adapter.targetMethod2(); } }
5.結果輸出
通過上面結果輸出我們可以得道以下幾點:
- 提供方法默認實現
- 決定子類必須要實現方法
- 子類可以決定是否重新父類方法
- 通過接口和抽象類的結合,避免了在實現接口的子類中出現大量的“無意義”實現,這個“無意義”實現,被緩沖到了抽象類中
5、適配器模式的優缺點
5.1、優點
更好的復用性:系統需要使用現有的類,而此類的接口不符合系統的需要。那么通過適配器模式就可以讓這些功能得到更好的復用。
更好的擴展性:在實現適配器功能的時候,可以擴展自己源的行為(增加方法),從而自然地擴展系統的功能。
5.2、缺點
會導致系統紊亂:濫用適配器,會讓系統變得非常零亂。例如,明明看到調用的是A接口,其實內部被適配成了B接口的實現,一個系統如果太多出現這種情況,無異於一場災難。因此如果不是很有必要,可以不使用適配器,而是直接對系統進行重構。