国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

設計模式---適配器模式

Y3G / 2334人閱讀

摘要:根據適配器類與適配者類的關系不同,適配器模式可分為對象適配器和類適配器兩種,在對象適配器模式中,適配器與適配者之間是關聯聚合關系在類適配器模式中,適配器與適配者之間是繼承或實現關系。


適配器概念介紹

1、不同國家的插座是有區別的,如果我們去國外旅游,需要帶上國外的插頭轉換器,來能兼容國外的插座;

2、手機的耳機孔有圓頭和扁頭,如果扁頭的耳機孔想接圓頭的耳機就需要一個耳機的轉換器;


上述所說的轉換器,其實就是適配器;它是用來做兼容的;


介紹

適配器模式(Adapter Pattern):將一個接口轉換成客戶希望的另一個接口,使接口不兼容的那些類可以一起工作,其別名為包裝器(Wrapper)。適配器模式既可以作為類結構型模式,也可以作為對象結構型模式。

在適配器模式中,我們通過增加一個新的適配器類來解決接口不兼容的問題,使得原本沒有任何關系的類可以協同工作。

根據適配器類與適配者類的關系不同,適配器模式可分為對象適配器和類適配器兩種,在對象適配器模式中,適配器與適配者之間是關聯(聚合)關系;在類適配器模式中,適配器與適配者之間是繼承(或實現)關系。


角色

Target(目標抽象類):目標抽象類定義客戶所需接口,可以是一個抽象類或接口,也可以是具體類。

Adapter(適配器類):適配器可以調用另一個接口,作為一個轉換器,對Adaptee和Target進行適配,適配器類是適配器模式的核心,在對象適配器中,它通過繼承Target并關聯一個Adaptee對象使二者產生聯系。

Adaptee(適配者類—適配接口):適配者即被適配的角色,它定義了一個已經存在的接口,這個接口需要適配,適配者類一般是一個具體類,包含了客戶希望使用的業務方法,在某些情況下可能沒有適配者類的源代碼。

缺省適配器模式(Default Adapter Pattern):當不需要實現一個接口所提供的所有方法時,可先設計一個抽象類實現該接口,并為接口中每個方法提供一個默認實現(空方法),那么該抽象類的子類可以選擇性地覆蓋父類的某些方法來實現需求,它適用于不想使用一個接口中的所有方法的情況,又稱為單接口適配器模式。


工作原理

  • 適配器模式:將一個類的接口轉換成另一種接口,讓原本接口不兼容的類可以兼容;
  • 從用戶的角度看不到被適配者;
  • 用戶調用適配器轉化出來的目標接口方法,適配器再調用被適配者的相關接口方法;

3種適配器模式

  • 類適配器模式
  • 對象適配器模式
  • 接口適配器模式

類適配器模式演示

以生活中充電器為例,充電器本身相當于適配者 (Adapter),220V 交流電相當于被適配者,我們的目標(target) 想把220V交流電轉成5V直流電

要適配的類,即需要將220v電壓轉化為5v電壓

//中國的電壓220Vpublic class ChinaPower{    private final Integer outPut=220;    public Integer getOutPut() {        return outPut;    }}

適配器接口,只負責定義轉化需要使用的業務邏輯方法,具體實現交由適配器類完成

//將電壓轉化為5v---適配接口public interface TransTo5V{    Integer transTo5V();}

適配器類,繼承了ChinaPower,并實現了適配器接口,負責實現講220v電壓轉化為5v的具體業務邏輯代碼實現

//適配器類---實現適配器接口public class ChinaAdapter extends ChinaPower implements TransTo5V{    //將220v電壓轉換為5v的    @Override    public Integer transTo5V()    {        //獲得被適配類,即我們需要將220v電壓轉化為5v返回        Integer output=super.getOutPut();        //進行電壓轉換操作        return output/44;    }}

Phone類,需要用到適配器進行兼容,這樣才可以充電

//手機需要5v的電壓進行充電public class Phone{    //通過適配器獲得5v的電壓    public void charging(ChinaAdapter chinaAdapter)    {        if(5==chinaAdapter.transTo5V())        {            System.out.println("得到5v,充電中...");        }        else        {            System.out.println("電壓過高,手機壓力過大");        }    }}

充電測試

public class test{    @Test    public void test()    {        Phone p=new Phone();        p.charging(new ChinaAdapter());    }}


對象適配器模式

還是以上面的例子為例,這一次適配器類不再繼承ChinaPower ,而是以聚合的方式來代替繼承,符合設計模式中的"合成復用原則";java是單繼承機制,這樣可以保留對象繼承權;

我們只需要修改適配器類即可:

//適配器類---實現適配器接口public class ChinaAdapter implements TransTo5V{    private ChinaPower chinaPower;    //通過構造器,完成賦值    public ChinaAdapter(ChinaPower chinaPower)    {     this.chinaPower=chinaPower;       }    //將220v電壓轉換為5v的    @Override    public Integer transTo5V()    {        //獲得被適配類,即我們需要將220v電壓轉化為5v返回        Integer output=chinaPower.getOutPut();        //進行電壓轉換操作        return output/44;    }}

測試

public class test{    @Test    public void test()    {        Phone p=new Phone();        p.charging(new ChinaAdapter(new ChinaPower()));    }}

對象適配器的優點

對象適配器和類適配器其實算是同一種思想,只不過實現方式不同。根據合成復用原則,使用組合替代繼承, 所以它解決了類適配器必須繼承被適配者的局限性問題;


接口適配器模式

  • 接口適配器模式(Default Adapter Pattern),也叫缺省適配器模式;
  • 核心思路:當不需要全部實現接口提供的方法時,可先設計一個抽象類實現接口,并為該接口中每個方法提供一個默認實現(空方法),該抽象類的子類可有選擇地覆蓋父類的某些方法來實現需求;
  • 適用于一個接口不想使用其所有的方法的情況;

定義一個適配器接口:

public interface InterfaceTest {	public void m1();	public void m2();	public void m3();	public void m4();}

抽象類 AbsAdapter 將 InterfaceTest 的方法進行默認實現,當子類需要使用適配器接口中的某個方法,而不是全部方法時,就可以通過繼承抽象類,來完成對需要使用的特定方法重寫操作即可,無需實現適配器接口里面的全部方法

public abstract class AbsAdapter implements InterfaceTest {	//默認實現	public void m1() {}	public void m2() {}	public void m3() {}	public void m4() {}}

Client 調用接口,重寫適配器抽象類方法

public class Client {	public static void main(String[] args) {				AbsAdapter absAdapter = new AbsAdapter() {			//只需要去覆蓋我們 需要使用 接口方法			@Override			public void m1() {				System.out.println("使用了m1的方法");			}		};				absAdapter.m1();	}}

綜合小案例—使用類適配器模式

power–帶轉換的電壓

一個頂層接口Power

public interface Power{     Integer getOutPut();}

分支一: 中國的220v電壓

//中國的電壓220Vpublic class ChinaPower implements Power{    private final Integer outPut=220;    @Override    public Integer getOutPut() {        return outPut;    }}

分支二: 日本的110v電壓

//日本電壓110vpublic class JapenPower implements Power{    private final Integer output=110;    @Override    public Integer getOutPut() {        return output;    }}

adapter–適配器

失配器接口–DC5Adapter

//適配器接口public interface DC5Adapter{    boolean support(Power power);    Integer transTo5V(Power power);}

適配器類—ChinaAdapter–只負責將220v電壓進行轉換的工作

//該適配器負責將中國的220v電壓轉化為5v的電壓public class ChinaAdapter implements DC5Adapter{    //當前適配器只負責將220v電壓轉化為5v的功能實現    private  static Integer voltage=220;    //判斷當前適配器能否勝任傳入power電壓的轉化職責    @Override    public boolean support(Power power)    {      if(power.getOutPut().equals(voltage))      return true;      return false;    }    //將220v電壓轉換為5v的    @Override    public Integer transTo5V(Power power)    {        //獲得被適配類,即我們需要將220v電壓轉化為5v返回        Integer output=power.getOutPut();        //進行電壓轉換操作        return output/44;    }}

適配器類—JapenAdapter–只負責將110v電壓進行轉換的工作

//該適配器負責將日本的110v電壓轉化為5v的電壓public class JapenAdapter implements DC5Adapter{    //當前適配器只負責將110v電壓轉化為5v的功能實現    private  static Integer voltage=110;    //判斷是否支持將日本110v電壓轉化為5v電壓的操作    @Override    public boolean support(Power power) {        if(power.getOutPut()==voltage)            return true;        return false;    }    //將110v電壓轉換為5v的    @Override    public Integer transTo5V(Power power)    {        //獲得被適配類,即我們需要將110v電壓轉化為5v返回        Integer output=power.getOutPut();        //進行電壓轉換操作        return output/22;    }}

FindAdapter–尋找合適的適配器

//手機需要5v的電壓進行充電public class FindAdapter{    //存放所有適配器的set集合    private static final Set<DC5Adapter> DC5Adapters=new HashSet<>();    //通過靜態代碼塊進行初始化操作    static    {        DC5Adapters.add(new ChinaAdapter());        DC5Adapters.add(new JapenAdapter());    }    // 根據電壓找合適的變壓器    public DC5Adapter getPowerAdapter(Power power)    {        DC5Adapter dc5Adapter=null;        for(DC5Adapter da:DC5Adapters)        {            //如果遍歷到當前電壓合適的變壓器就直接退出遍歷            if(da.support(power))            {                dc5Adapter=da;                break;            }        }        //如果遍歷完所有的變壓器都沒有找到合適的,就拋出異常        if(dc5Adapter==null)        {            throw  new IllegalArgumentException("未能找到合適的變壓器");        }        //返回找到的合適的變壓器        return dc5Adapter;    }}

測試

public class test{    @Test    public void test()    {        //找尋合適的變壓器是第一步        FindAdapter fa=new FindAdapter();        //找尋可以將220v轉化為5v的變壓器,即適配器        DC5Adapter adapter = fa.getPowerAdapter(new ChinaPower());        //輸出當前變壓器轉化之后的電壓        System.out.println(adapter.transTo5V(new ChinaPower()));    }}


適配器模式總結

主要優點

  • 將目標類和適配者類解耦,通過引入一個適配器類來重用現有的適配者類,無須修改原有結構。
  • 增加了類的透明性和復用性,將具體的業務實現過程封裝在適配者類中,對于客戶端類而言是透明的,而且提高了適配者的復用性,同一個適配者類可以在多個不同的系統中復用。
  • 靈活性和擴展性都非常好,通過使用配置文件,可以很方便地更換適配器,也可以在不修改原有代碼的基礎上增加新的適配器類,完全符合“開閉原則”。

具體來說,類適配器模式還有如下優點:

  • 由于適配器類是適配者類(適配器接口或適配器接口實現的抽象類)的子類,因此可以在適配器類中置換一些適配者(適配器接口或適配器接口實現的抽象類)的方法,使得適配器的靈活性更強。
  • 一個對象適配器可以把多個不同的適配者(適配器接口或適配器接口實現的抽象類)適配到同一個目標;
  • 可以適配一個適配者的子類,由于適配器和適配者(適配器接口或適配器接口實現的抽象類)之間是關聯關系,根據“里氏代換原則”,適配者(適配器接口或適配器接口實現的抽象類)的子類也可通過該適配器進行適配。

主要缺點

  • 對于Java、C#等不支持多重類繼承的語言,一次最多只能適配一個適配者類(適配器接口或適配器接口實現的抽象類),不能同時適配多個適配者;
  • 適配者類不能為最終類,如在Java中不能為final類,C#中不能為sealed類;
  • 在Java、C#等語言中,類適配器模式中的目標抽象類只能為接口,不能為類,其使用有一定的局限性。
  • 與類適配器模式相比,要在適配器中置換適配者類的某些方法比較麻煩。如果一定要置換掉適配者類的一個或多個方法,可以先做一個適配者類的子類,將適配者類的方法置換掉,然后再把適配者類的子類當做真正的適配者進行適配,實現過程較為復雜。

適用場景

  • 系統需要使用一些現有的類,而這些類的接口(如方法名)不符合系統的需要,甚至沒有這些類的源代碼。
  • 想創建一個可以重復使用的類,用于與一些彼此之間沒有太大關聯的一些類,包括一些可能在將來引進的類一起工作。

spring MVC中的適配器模式

springMVC處理請求流程

  • 第1步 用戶發送請求至前端控制器DispatcherServlet;
  • 第2,3步DispatcherServlet收到請求,根據請求url調用HandlerMapping處理器映射器找到具體的處理器;生成處理器對象及處理器攔截器(如果有則生成)一并返回給DispatcherServlet;
  • 第4步 DispatcherServlet通過HandlerAdapter處理器適配器調用具體的處理器;(這一步用到適配者模式)
  • 第5,6步 執行處理器(Controller,也叫后端控制器),返回ModelAndView;
  • 第7步 HandlerAdapter將controller執行結果ModelAndView返回給DispatcherServlet
  • 第8步DispatcherServlet將ModelAndView傳給ViewReslover視圖解析器(但是如果加上@responsebody注解,則返回值不通過viewResolver,而是直接返回object);
  • 第9步 ViewReslover解析后返回具體View;
  • 第10步 DispatcherServlet對View進行渲染視圖(即將模型數據填充至視圖中);
  • 第11步 DispatcherServlet響應用戶。

SpringMVM 中的 HandlerAdapter(上圖的第4步), 就使用了適配器模式;


請求處理方法中適配器模式部分源碼探究

Spring MVC中的適配器模式主要用于執行目標 Controller 中的請求處理方法。

在Spring MVC中,DispatcherServlet 作為用戶,HandlerAdapter 作為期望接口(適配器接口),具體的適配器實現類用于對目標類進行適配,Controller 作為需要適配的類。

為什么要在 Spring MVC 中使用適配器模式?Spring MVC 中的 Controller 種類眾多,不同類型的 Controller 通過不同的方法來對請求進行處理。如果不利用適配器模式的話,DispatcherServlet 直接獲取對應類型的 Controller,需要的自行來判斷,像下面這段代碼一樣:

if(mappedHandler.getHandler() instanceof MultiActionController){     ((MultiActionController)mappedHandler.getHandler()).xxx  }else if(mappedHandler.getHandler() instanceof XXX){      ...  }else if(...){     ...  }  

這樣假設如果我們增加一個 HardController,就要在代碼中加入一行 if(mappedHandler.getHandler() instanceof HardController),這種形式就使得程序難以維護,也違反了設計模式中的開閉原則 – 對擴展開放,對修改關閉。

我們來看看源碼,首先是適配器接口 HandlerAdapter

//適配器接口public interface HandlerAdapter {    //判斷當前的controller請求是否能被當前的適配器類處理    boolean supports(Object var1);            //只有當支持處理當前請求后,才會執行下面的處理請求方法,返回一個ModelAndView對象     ModelAndView handle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception;    long getLastModified(HttpServletRequest var1, Object var2);}

現該接口的適配器每一個 Controller 都有一個適配器與之對應,這樣的話,每自定義一個 Controller 需要定義一個實現 HandlerAdapter 的適配器。

springmvc 中提供的 Controller 實現類有如下:

springmvc 中提供的 HandlerAdapter 實現類如下

HttpRequestHandlerAdapter 這個適配器代碼如下:

//不同的適配器類實現不同的功能//當前的HttpRequestHandlerAdapter 適配器類,只負責處理關于HttpRequest相關的請求public class HttpRequestHandlerAdapter implements HandlerAdapter {    public HttpRequestHandlerAdapter() {    }        //判斷當前的controller請求是否是HttpRequestHandler類型的    //當前適配器只支持處理當前類型的handler     public boolean supports(Object handler) {        return handler instanceof HttpRequestHandler;    }    //如果驗證支持,會調用下面這個方法進行具體邏輯處理    public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {    //先進行強制類型轉換,轉換為指定的handler類型,然后就可以調用該類型處理對應請求的方法了    //調用HttpRequestHandler的handleRequest處理對應的請求        ((HttpRequestHandler)handler).handleRequest(request, response);        return null;    }    public long getLastModified(HttpServletRequest request, Object handler) {        return handler instanceof LastModified ? ((LastModified)handler).getLastModified(request) : -1L;    }}

當Spring容器啟動后,會將所有定義好的適配器對象存放在一個List集合中,當一個請求來臨時,DispatcherServlet 會通過 handler 的類型找到對應適配器,并將該適配器對象返回給用戶,然后就可以統一通過適配器的 hanle() 方法來調用 Controller 中的用于處理請求的方法。

public class DispatcherServlet extends FrameworkServlet {//用于存放所有HandlerAdapter適配器類的list集合    private List<HandlerAdapter> handlerAdapters;        //初始化handlerAdapters    private void initHandlerAdapters(ApplicationContext context) {        //..省略...    }        // 遍歷所有的 HandlerAdapters,通過 supports 判斷找到匹配的適配器    protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {		for (HandlerAdapter ha : this.handlerAdapters) {			if (logger.isTraceEnabled()) {				logger.trace("Testing handler adapter [" + ha + "]");			}			if (ha.supports(handler)) {				return ha;			}		}	}		// 分發請求,請求需要找到匹配的適配器來處理	protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {		HttpServletRequest processedRequest = request;
            
                     
             
               

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/118905.html

相關文章

  • PHP設計模式(十):配器模式

    摘要:原文地址設計模式十適配器模式在設計模式七設計模式分類中我們提到過結構設計模式,結構設計模式專注于設計對象和實例的構建組合過程。適配器模式在不修改現有代碼的基礎上,保留了架構。 原文地址:PHP設計模式(十):適配器模式 Introduction 在PHP設計模式(七):設計模式分類中我們提到過結構設計模式(Structural patterns),結構設計模式專注于設計對象(Objec...

    paney129 評論0 收藏0
  • 一天一個設計模式之JS實現——配器模式

    摘要:本文參考于設計模式課程設計模式之適配器模式設計模式是一套被反復使用的多數人知曉的經過分類編目的代碼設計經驗的總結。第一個設計模式是適配器模式??偟膩碚f適配器就是的模式,與修飾模式直接無感使用不同,適配器模式使用對象變為。 本文參考于:設計模式課程設計模式之適配器模式 設計模式是一套被反復使用的、多數人知曉的、經過分類編目的、代碼設計經驗的總結。使用設計模式是為了重用代碼、讓代碼更容易被...

    Aceyclee 評論0 收藏0
  • 深入理解配器模式

    摘要:組件目標角色客戶端所期待得到的接口,適配器角色適配器類是本模式的核心。最后附上一張適配器的概覽圖參考適配器模式與模式之適配器模式基礎淺談常見設計模式適配器模式原理及實例介紹適配器模式裝飾模式代理模式的異同 適配器模式 說到適配器,小秋第一想到的是我們電腦的電源適配器,它能夠將220v,110v等不同電壓轉換為我們電腦需要的電壓值供電腦使用,那么你知道適配器模式是怎樣實現的嗎,下面就和小...

    Rindia 評論0 收藏0
  • JavaScript 設計模式(四):適配模式

    摘要:與其它模式的異同適配器模式不會改變原有接口,這一點與裝飾者模式和代理模式類似。代理模式適配器模式與代理模式最相似,同樣都是創建一個新對象包裝一次,實現對本體的調用。外觀模式外觀模式與適配器模式最大的區別,是定義了一個新的接口。 showImg(https://segmentfault.com/img/bVbul8d?w=800&h=600); 適配器模式:將一個類(對象)的接口(方法或...

    MingjunYang 評論0 收藏0
  • 淺談25種設計模式(4/25)(此坑未填)

    摘要:適配器模式橋接模式過濾器模式組合模式裝飾器模式外觀模式享元模式代理模式行為型模式這些設計模式特別關注對象之間的通信。對象適配器另外一種適配器模式是對象適配器,它不是使用多繼承或繼承再實現的方式,而是使用直接關聯,或者稱為委托的方式。 設計模式匯總 創建型模式 這些設計模式提供了一種在創建對象的同時隱藏創建邏輯的方式,而不是使用新的運算符直接實例化對象。這使得程序在判斷針對某個給定實例需...

    0xE7A38A 評論0 收藏0

發表評論

0條評論

Y3G

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<