現實生活中的適配器例子html
泰國插座用的是兩孔的(歐標),能夠買個多功能轉換插頭 (適配器) ,這樣就能夠
使用了。java
基本介紹
1) 適配器模式( Adapter Pattern )將某個類的接口轉換成客戶端指望的另外一個接口表示,主的目的是兼容性,讓本來因接口不匹配不能一塊兒工做的兩個類能夠協同工做。其別名爲包裝器(Wrapper)
2) 適配器模式屬於結構型模式
3) 主要分爲三類:類適配器模式、對象適配器模式、接口適配器模式設計模式
工做原理
1) 適配器模式:將一個類的接口轉換成另外一種接口.讓本來接口不兼容的類能夠兼容
2) 從用戶的角度看不到被適配者,是解耦的
3) 用戶調用適配器轉化出來的目標接口方法,適配器再調用被適配者的相關接口方法
4) 用戶收到反饋結果,感受只是和目標接口交互,如圖(關鍵詞:src,adapter,dst )app
類適配器模式
基本介紹:
Adapter 類,經過繼承 src 類,實現 dst 類接口,完成 src->dst 的適配。
(Adapter extends src implements dst )
應用實例:
1) 應用實例說明
以生活中充電器的例子來說解適配器,充電器自己至關於Adapter,220V交流電至關於src (即被適配者),咱們的目dst(即 目標)是5V直流電
2) 思路分析(類圖)框架
3) 代碼實現ide
//被適配的類 public class Voltage220V { //輸出220V的電壓 public int output220V() { int src = 220; System.out.println("電壓=" + src + "伏"); return src; } } //適配接口 public interface IVoltage5V { public int output5V(); } //適配器類 public class VoltageAdapter extends Voltage220V implements IVoltage5V { @Override public int output5V() { //獲取到220V電壓 int srcV = output220V(); int dstV = srcV / 44 ; //轉成 5v return dstV; } } public class Phone { //充電 public void charging(IVoltage5V iVoltage5V) { if(iVoltage5V.output5V() == 5) { System.out.println("電壓爲5V, 能夠充電~~"); } else if (iVoltage5V.output5V() > 5) { System.out.println("電壓大於5V, 不能充電~~"); } } } public class Client { public static void main(String[] args) { // TODO Auto-generated method stub System.out.println(" === 類適配器模式 ===="); Phone phone = new Phone(); phone.charging(new VoltageAdapter()); } }
類適配器模式注意事項和細節
1) Java 是單繼承機制,因此類適配器須要 繼承 src 類這一點算是一個缺點, 由於這要求 dst 必須是接口,有必定侷限性;
2) src 類的方法在 Adapter 中都會暴露出來,也增長了使用的成本。
3) 因爲其繼承了 src 類,因此它能夠根據需求重寫 src 類的方法,使得 Adapter 的靈活性加強了。源碼分析
對象適配器模式
基本介紹:
1) 基本思路 和 類的適配器模式 相同,只是將 Adapter 類做修改,不是繼承src類,而是持有src類的實例,以解決兼容性的問題。 即:持有 src類,實現 dst 類接口,完成src->dst的適配
2) 根據「合成複用原則」,在系統中儘可能使用 關聯關係 來替代 繼承關係。
3) 對象適配器模式是適配器模式經常使用的一種動畫
應用實例:
1) 應用實例說明
以生活中充電器的例子來說解適配器,充電器自己至關於Adapter,220V交流電至關於src (即被適配者),咱們的目dst(即目標)是5V直流電,使用對象適配器模式完成。
2) 思路分析(類圖):只需修改適配器便可, 以下:this
3)代碼實現spa
//被適配的類 public class Voltage220V { //輸出220V的電壓,不變 public int output220V() { int src = 220; System.out.println("電壓=" + src + "伏"); return src; } } //適配接口 public interface IVoltage5V { public int output5V(); } //適配器類 public class VoltageAdapter implements IVoltage5V { private Voltage220V voltage220V; // 關聯關係-聚合 //經過構造器,傳入一個 Voltage220V 實例 public VoltageAdapter(Voltage220V voltage220v) { this.voltage220V = voltage220v; } @Override public int output5V() { int dst = 0; if(null != voltage220V) { int src = voltage220V.output220V();//獲取220V 電壓 System.out.println("使用對象適配器,進行適配~~"); dst = src / 44; System.out.println("適配完成,輸出的電壓爲=" + dst); } return dst; } } public class Phone { //充電 public void charging(IVoltage5V iVoltage5V) { if(iVoltage5V.output5V() == 5) { System.out.println("電壓爲5V, 能夠充電~~"); } else if (iVoltage5V.output5V() > 5) { System.out.println("電壓大於5V, 不能充電~~"); } } } public class Client { public static void main(String[] args) { System.out.println(" === 對象適配器模式 ===="); Phone phone = new Phone(); phone.charging(new VoltageAdapter(new Voltage220V())); } }
對象適配器模式注意事項和細節
1) 對象適配器和類適配器其實算是同一種思想,只不過實現方式不一樣。根據合成複用原則,使用組合替代繼承, 因此它解決了類適配器必須繼承src的侷限性問題,也再也不要求 dst 必須是接口。
2) 使用成本更低,更靈活。
接口適配器模式
基本介紹:
1) 一些書籍稱爲:適配器模式(Default Adapter Pattern)或缺省適配器模式。
2) 當不須要所有實現接口提供的方法時,可先設計一個抽象類實現接口,併爲該接口中每一個方法提供一個默認實現(空方法),那麼該抽象類的子類可有選擇地覆蓋父類的某些方法來實現需求
3) 適用於一個接口不想使用其全部的方法的狀況。
應用實例:
1) Android中的屬性動畫 ValueAnimator 類能夠經過 addListener ( AnimatorListener listener )方法添加監聽器, 那麼常規寫法以下:
ValueAnimator valueAnimator = ValueAnimator.ofInt(0,100); valueAnimator.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }); valueAnimator.start();
2) 有時候咱們不想實現 Animator.AnimatorListener 接口的所有方法,咱們只想監聽 onAnimationStart,咱們會以下寫:
ValueAnimator valueAnimator = ValueAnimator.ofInt(0,100); valueAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { //xxxx具體實現 } }); valueAnimator.start();
應用實例:
3) AnimatorListenerAdapter 類,就是一個接口適配器,代碼如右圖:它空實現了
Animator.AnimatorListener類(src)的全部方法.
4) AnimatorListener 是一個接口.
public abstract class AnimatorListenerAdapter implements Animator.AnimatorListener{ @Override //默認實現 public void onAnimationCancel(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationPause(Animator animation) { } @Override public void onAnimationResume(Animator animation) { } } public static interface AnimatorListener { void onAnimationStart(Animator animation); void onAnimationEnd(Animator animation); void onAnimationCancel(Animator animation); void onAnimationRepeat(Animator animation); }
5) 程序裏的匿名內部類就是Listener 具體實現類
案例說明:
public interface Interface4 { public void m1(); public void m2(); public void m3(); public void m4(); } //在AbsAdapter 咱們將 Interface4 的方法進行默認實現 public abstract class AbsAdapter implements Interface4 { //默認實現 public void m1() {} public void m2() {} public void m3() {} public void m4() {} } public class Client { public static void main(String[] args) { AbsAdapter absAdapter = new AbsAdapter() { //只須要去覆蓋咱們 須要使用 接口方法 @Override public void m1() { System.out.println("使用了m1的方法"); } }; absAdapter.m1(); } }
適配器模式在SpringMVC框架應用的源碼分析
1) SpringMvc 中的 HandlerAdapter , 就使用了適配器模式
2) SpringMVC 處理請求的流程回顧:(https://www.cnblogs.com/sanjun/p/9966666.html)(參考使用,侵刪)
3) 使用 HandlerAdapter 的緣由分析:
能夠看處處理器的類型不一樣,有多重實現方式,那麼調用方式就不是肯定的,若是須要直接調用
Controller方法,須要調用的時候就得不斷是使用if else來進行判斷是哪種子類而後執行。那麼若是後面要擴展Controller,就得修改原來的代碼,這樣違背了OCP原則。
4) 代碼分析+Debug源碼
5) 動手寫 SpringMVC 經過 適配器設計模式 獲取到對應的 Controller 的源碼
說明:
• Spring 定義了一個適配接口,使得每一種 Controller 有一種對應的適配器實現類
• 適配器代替controller執行相應的方法
• 擴展 Controller 時,只須要增長一個適配器類就完成了SpringMVC的擴展了,
• 這就是設計模式的力量
適配器模式的注意事項和細節
1) 三種命名方式,是根據 src是以怎樣的形式給到Adapter(在Adapter裏的形式)來命名的。
2) 類適配器:以類給到,在Adapter裏,就是將src當作類,繼承;
對象適配器:以對象給到,在Adapter裏,將src做爲一個對象,持有
接口適配器:以接口給到,在Adapter裏,將src做爲一個接口,實現3) Adapter模式最大的做用仍是將本來不兼容的接口融合在一塊兒工做。4) 實際開發中,實現起來不拘泥於咱們講解的三種經典形式