在學習SpringMVC時,發現了HandlerAdapter這個類採用了以前據說過的適配器模式, 所以專門來學習一下適配器模式編程
參考博客:http://www.javashuo.com/article/p-mvxpckhc-dr.htmlapp
https://blog.csdn.net/u012359453/article/details/79165080ide
http://www.javashuo.com/article/p-dttrsjqc-hg.html學習
一.適配器模式概念this
適配器模式是將某個類的接口轉換成客戶但願的另外一種接口. 適配器模式(Adapter Pattern)是做爲兩個不兼容的接口之間的橋樑, 它結合了兩個接口的功能.spa
用編程概念解釋就是, 你有一個接口,和其實現類, 可是這個接口實現的功能並不能徹底知足你的須要, 因而你實現了另外一個接口, 這個接口只須要在前一個接口實現的功能上加以修改就能知足你的須要, 可是兩個接口的功能是不能兼容的. 因而就有了適配器模式, 來讓兩個接口兼容..net
用通常解釋適配器的例子, 通俗講就是 你有一個220V的電壓電源, 可是你的手機只能支持5V電壓充電, 因而你須要有一個能將220V電壓轉換成5V電壓的適配器, 來讓你手機充電.設計
二.適配器模式定義code
適配器模式是結構型模式對象
三類適配器模式: 類適配器模式 , 對象適配器模式 , 接口適配器模式
適配器模式的術語: 1.目標(Target)接口: 當前系統業務所期待的接口,它能夠是抽象類或接口
2.適配者(Adaptee)類: 它是被訪問和適配的現有組件庫中的組件接口
3.適配器(Adapter)類: 它是一個轉換器,經過繼承或引用Adaptee的對象, 把Adaptee接口轉換成目標接口.
使用場景:
1.系統須要使用現有的類, 而這些類的接口不符合系統的須要
2.想要創建一個能夠重複使用的類, 用於一些彼此之間沒有太大關聯的類, 包括一些可能在未來引進的類一塊兒工做.
3.須要一個統一的輸出接口,而輸入端的類型不可預知.
三.適配器模式的實現
1.類適配器模式:
Adapter類, 經過繼承Adaptee類, 並實現Taget接口 , 完成Adaptee >>> Target的適配
(1)首先實現Adaptee類
這是一個輸出220V電壓的電源
public class Voltage220 { public int output220V(){ int src = 220; System.out.println("輸出電壓:"+src+"V"); return src; } }
(2)再實現Target接口
這個接口要實現一個輸出5V的電源
public interface Voltage5 { int output5V(); }
(3)而後實現類適配器, 讓二者兼容
適配器經過繼承Adaptee類, 實現Target接口,來將二者結合
//適配器的第一種方式: 類適配器模式 public class VoltageAdapter extends Voltage220 implements Voltage5 { @Override public int output5V() { int src = output220V(); System.out.println("適配器轉換電壓"); int dst = src/44; System.out.println("適配器輸出電壓:"+dst+"V"); return dst; } }
問題: 1.爲啥要先繼承Voltage220,而不是直接實現Voltage5接口,而後在類裏調用Voltage220呢?
答:這是適配器的第二種實現方式, 對象的適配器模式, 也是適配器模式的一種
2.爲啥不能讓Voltage220直接實現Voltage5的接口呢?
答:由於在使用Voltage220的時候,有可能Voltage5接口是不須要的累贅,或者你還要實現其餘接口.另外,這樣會增長耦合性, 使Voltage220難以擴展其它多的功能. 好比下次若是你還要實現一個Voltage10的接口,Voltage20的接口,不可能一直往上面實現.
2.對象適配器模式
Adapter類持有Adaptee類, 實現Target接口, 完成Adaptee >>> Target的適配
(1)實現Adaptee類: 與上面代碼同樣
public class Voltage220 { public int output220V(){ int src = 220; System.out.println("輸出電壓:"+src+"V"); return src; } }
(2)Target接口:
public interface Voltage5 { int output5V(); }
(3)Adapter實現:
//適配器的第二種方式: 對象適配器模式 public class VoltageAdapter2 implements Voltage5 { private Voltage220 voltage220; public VoltageAdapter2(Voltage220 voltage220){ this.voltage220 = voltage220; } @Override public int output5V() { int dst = 0; if(null != voltage220){ int src = voltage220.output220V(); System.out.println("適配器轉換電壓"); dst = src/44; System.out.println("適配器輸出電壓"+dst+"V"); } return dst; } }
注意:與裝飾器模式的區別, 裝飾器持有的對象和裝飾器實現的是同一接口, 且裝飾器模式的目的是加強功能
3.接口的適配器模式:
也叫認識適配器模式或缺省適配器模式
當你要使用一個接口的提供的某一個方法, 而不須要所有實現接口提供的方法時, 能夠先設計一個抽象類實現接口, 併爲接口中的每一個方法默認實現(空實現), 那麼該抽象類的子類能夠有選擇地覆蓋父類的某些方法來實現其想要的方法, 而不是實現所有方法.
(1)實現Adaptee類:
public class Voltage220 { public int output220V(){ int src = 220; System.out.println("輸出電壓:"+src+"V"); return src; } }
(2)設計Target接口, 設計一個抽象類來空實現Target接口的方法:
public interface SuperVoltage { int output5V(); int output10V(); int output20V(); int output40V(); int output220V(); }
//適配器模式的第三種: 接口適配器模式, 或者叫認識適配器模式, 缺省適配器模式 public abstract class SuperVoltageAdapter implements SuperVoltage{ @Override public int output5V() { return 0; } @Override public int output10V() { return 0; } @Override public int output20V() { return 0; } @Override public int output40V() { return 0; } @Override public int output220V() { return 0; } }
(3)抽象類的子類就能夠有選擇地實現其須要的方法:
①5V輸出:
public class VoltageAdapter3 extends SuperVoltageAdapter { private Voltage220 voltage220; public VoltageAdapter3(Voltage220 voltage220){ this.voltage220 = voltage220; } @Override public int output5V(){ int dst = 0; if(voltage220 != null){ int src = voltage220.output220V(); dst = src/44; System.out.println("適配器轉換電壓"); } return dst; } }
②10V輸出:
public class VoltageAdapter3 extends SuperVoltageAdapter { private Voltage220 voltage220; public VoltageAdapter3(Voltage220 voltage220){ this.voltage220 = voltage220; } @Override public int output10V(){ int dst = 0; if(voltage220 != null){ int src = voltage220.output220V(); dst = src/22; System.out.println("適配器轉換電壓"); } return dst; } }
四.適配器模式的應用
該段取自博客:http://www.javashuo.com/article/p-dttrsjqc-hg.html
SpringMVC中的適配器模式:
在SpringMVC中 , DispatcherServlet是用戶, HandlerAdapter是Target接口, Controller是Adaptee
因此SpringMVC實現了多個適配器,來將Controller轉換適應HandlerAdapter接口
(1)Target: HandlerAdapter接口的方法
public interface HandlerAdapter { boolean supports(Object var1); ModelAndView handle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception; long getLastModified(HttpServletRequest var1, Object var2); }
supports方法是判斷Controller是不是該適配器符合的Controller類型
handle方法 來執行Controller中的請求處理
(2)Adaptee: SpringMVC中的Controller實現類
這裏不提供具體代碼, 只提供有哪些類型
(3)Adapter: SpringMVC中的適配器實現
SpringMVC中如何實現適配的:
當Spring容器啓動後,會將全部定義好的適配器對象存放在一個List集合中,當一個請求來臨時,DispatcherServlet 會經過 handler 的類型找到對應適配器,並將該適配器對象返回給用戶,而後就能夠統一經過適配器的 hanle() 方法來調用 Controller 中的用於處理請求的方法。
經過適配器模式咱們將全部的 controller
統一交給 HandlerAdapter
處理,免去了寫大量的 if-else
語句對 Controller
進行判斷,也更利於擴展新的 Controller
類型。