<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          無處不在的適配器模式

          共 4853字,需瀏覽 10分鐘

           ·

          2021-01-06 18:00

          點(diǎn)擊上方「藍(lán)字」關(guān)注我們


          0x01:適配器模式簡介

          ? ? ? ?對于適配器相信不會(huì)陌生,生活中的例子比比皆是,像耳機(jī)轉(zhuǎn)接線,充電器適配器,水管適配接口等等。通過類比很容易理解軟件中的適配器模式。

          ? ? ? ?客戶端需要一個(gè)target(目標(biāo))接口,但是不能直接重用已經(jīng)存在的adaptee(適配者)類,因?yàn)樗慕涌诤蛅arget接口不一致,所以需要adapter(適配器)將adaptee轉(zhuǎn)換為target接口。前提是target接口和已存在的適配者adaptee類所做的事情是相同或相似,只是接口不同且都不易修改。如果在設(shè)計(jì)之初,最好不要考慮這種設(shè)計(jì)模式。凡事都有例外,就是設(shè)計(jì)新系統(tǒng)的時(shí)候考慮使用第三方組件,因?yàn)闆]必要為了迎合第三方組件修改自己的軟件設(shè)計(jì)風(fēng)格,可以嘗試使用適配器模式。

          下面是一個(gè)非常典型的使用適配器模式的場景:

          ? ? ? ?Sun公司在1996年公開了Java語言的數(shù)據(jù)庫連接工具JDBC,JDBC使得Java語言程序能夠與數(shù)據(jù)庫連接,并使用SQL語言來查詢和操作數(shù)據(jù)。JDBC給出一個(gè)客戶端通用的抽象接口,每一個(gè)具體數(shù)據(jù)庫廠商(如SQL Server、Oracle、MySQL等)的JDBC驅(qū)動(dòng)軟件都是一個(gè)介于JDBC接口和數(shù)據(jù)庫引擎接口之間的適配器軟件。抽象的JDBC接口和各個(gè)數(shù)據(jù)庫引擎API之間都需要相應(yīng)的適配器軟件,這就是為各個(gè)不同數(shù)據(jù)庫引擎準(zhǔn)備的驅(qū)動(dòng)程序。

          ? ? ? ?另外一個(gè)比較典型的適配器場景J2EE規(guī)范與J2EE規(guī)范實(shí)現(xiàn)的服務(wù)器。SUN公司提供了一套J2EE規(guī)范,然后不同廠商根據(jù)自己的理解實(shí)現(xiàn)了不同的應(yīng)用服務(wù)器。SUN公司提供了一套servlet api規(guī)范,然后實(shí)現(xiàn)這套規(guī)范的著名應(yīng)用服務(wù)器有Apache Tomcat、Jetty、Oracle 的 Weblogic、IBM 的 WebSphere 等。

          適配器模式的UML類圖如下

          從類圖上看主要包含如下角色:

          目標(biāo)角色(target):這是客戶所期待的接口。目標(biāo)可以是具體的或抽象的類,也可以是接口;

          適配者角色(adaptee):已存在接口(可以理解是第三方提供的接口),但是和客戶端期待的接口不兼容;

          適配器角色(adapter):將已有接口轉(zhuǎn)換成目標(biāo)接口(可以理解我方需要的接口);


          0x02:適配器模式的實(shí)現(xiàn)

          • 類適配器模式(class adapter pattern)

          通過繼承進(jìn)行適配(類間繼承)。類適配器模式在編譯時(shí)實(shí)現(xiàn)target(目標(biāo))接口。這種適配器模式使用了多個(gè)實(shí)現(xiàn)了期待的接口或者已經(jīng)存在的接口的多態(tài)接口。比較典型的就是:target接口被創(chuàng)建為一個(gè)純粹的接口,Java不支持多繼承的語言。

          Target:Target目標(biāo)角色,該角色定義把其他類轉(zhuǎn)換為何種接口,也就是期望接口,通常情況下是一個(gè)接口或一個(gè)抽象類,一般不會(huì)是實(shí)現(xiàn)類

          public?interface?Target?{

          ?????public?void?request();

          }

          Adaptee:Adaptee源角色,想把誰轉(zhuǎn)換為目標(biāo)角色,這個(gè)“誰”就是源角色,它是已經(jīng)存在的、運(yùn)行良好的類或?qū)ο?/span>

          public?class?Adaptee?{

          ????public?void?specificRequest()?{
          ????????System.out.println("我是已經(jīng)存在的運(yùn)行良好的第三方廠商");
          ????}

          }

          Adapter:Adapter適配器角色,是適配器模式的核心角色,它的職責(zé)是通過繼承或是類關(guān)聯(lián)的方式把源角色轉(zhuǎn)換為目標(biāo)角色

          public?class?Adapter?extends?Adaptee?implements?Target?{

          ????@Override
          ????public?void?request()?{
          ????????super.specificRequest();
          ????}

          }

          ConcreteTarget:目標(biāo)角色的實(shí)現(xiàn)類

          public?class?ConcreteTarget?implements?Target?{

          ????@Override
          ????public?void?request()?{
          ????????System.out.println("沒有增加適配器的我方普通實(shí)現(xiàn)邏輯");
          ????}

          }

          類適配器模式測試代碼

          public?class?Client?{

          ????public?static?void?main(String[]?args)?{
          ????????//原有無適配器的業(yè)務(wù)邏輯
          ????????Target?target?=?new?ConcreteTarget();
          ????????target.request();

          ????????//增加適配器后的業(yè)務(wù)邏輯
          ????????Target?target2?=?new?Adapter();
          ????????target2.request();
          ????}

          }
          • 對象適配器模式(object adapter pattern)

          通過對象層次的關(guān)聯(lián)關(guān)系進(jìn)行委托(對象的合成關(guān)系/關(guān)聯(lián)關(guān)系)。對象適配器模式在運(yùn)行時(shí)實(shí)現(xiàn)target(目標(biāo))接口。在這種適配器模式中,適配器包裝了一個(gè)類實(shí)例。在這種情況下,適配器調(diào)用包裝對象實(shí)例的方法。

          Target:客戶所期待的接口。目標(biāo)可以是具體的或抽象的類,也可以是接口

          public?class?Target?{

          ????public?void?request()?{
          ????????System.out.println("沒有適配器的普通請求");
          ????}

          }

          Adaptee:需要適配的類

          public?class?Adaptee?{

          ????public?void?specificRequest()?{
          ????????System.out.println("適配器類實(shí)現(xiàn)的特殊請求");
          ????}

          }

          Adapter:通過在內(nèi)部包裝一個(gè)Adaptee對象,把源接口轉(zhuǎn)換成目標(biāo)接口

          public?class?Adapter?extends?Target?{

          ????private?Adaptee?adaptee?=?new?Adaptee();

          ????@Override
          ????public?void?request()?{
          ????????//替換原理的邏輯,調(diào)用適配類的邏輯
          ????????adaptee.specificRequest();
          ????}
          }

          對象適配器模式測試代碼

          public?class?Client?{

          ????public?static?void?main(String[]?args)?{
          ????????Target?target?=?new?Adapter();
          ????????target.request();
          ????}

          }
          • 缺省適配器模式(default adapter pattern),也叫默認(rèn)適配器模式、接口適配器模式

          當(dāng)不需要全部實(shí)現(xiàn)接口提供的方法時(shí),可以設(shè)計(jì)一個(gè)適配器抽象類實(shí)現(xiàn)接口,并為接口中的每個(gè)方法提供默認(rèn)方法實(shí)現(xiàn)或者空實(shí)現(xiàn)(如果大家做過GUI編程,就可以經(jīng)常遇到這種實(shí)現(xiàn),特別是各種控件的事件監(jiān)聽都提供了適配器類),抽象類的子類就可以有選擇的覆蓋父類的某些方法實(shí)現(xiàn)需求,它適用于一個(gè)接口不想使用所有的方法的情況。在java8后,接口中可以有default方法,就不需要這種缺省適配器模式了。接口中方法都設(shè)置為default,實(shí)現(xiàn)為空,這樣同樣同樣可以達(dá)到缺省適配器模式同樣的效果。

          target:包含了很多沒有實(shí)現(xiàn)的操作接口

          public?interface?Target?{
          ?????public?abstract?void?operation1();

          ?????public?abstract?void?operation2();

          ?????public?abstract?void?operation3();
          }

          Adapter默認(rèn)實(shí)現(xiàn)了所有操作抽象類,只是所有的實(shí)現(xiàn)都是空實(shí)現(xiàn)

          public?abstract?class?DefaultAdapter?implements?Target{

          ????@Override
          ????public?void?operation1()?{
          ????}

          ????@Override
          ????public?void?operation2()?{
          ????}

          ????@Override
          ????public?void?operation3()?{
          ????}

          }

          測試缺省適配器模式需要用到的類(相當(dāng)于GUI編程的一個(gè)組件,比如按鈕Button)

          public?class?Operator?{
          ????private?Target?target;

          ????public?void?addOperation(Target?target)?{
          ????????this.target=?target;
          ????}

          ????public?void?operation1()?{
          ????????target.operation1();
          ????}

          ????public?void?operation2()?{
          ????????target.operation2();
          ????}

          ????public?void?operation3()?{
          ????????target.operation3();
          ????}
          }

          缺省適配器模式測試代碼

          public?class?Client{

          ????public?static?void?main(String[]?args)?{
          ????????//?原來要實(shí)現(xiàn)所有操作類的操作
          ????????Operator?operator1=?new?Operator();
          ????????operator1.addOperation(new?Target()?{
          ????????????@Override
          ????????????public?void?operation1()?{}

          ????????????@Override
          ????????????public?void?operation2()?{
          ????????????????System.out.println("invoke?operation2");
          ????????????}

          ????????????@Override
          ????????????public?void?operation3()?{}

          ????????});
          ????????operator1.operation2();

          ????????//?2、使用缺省適配器只需要實(shí)現(xiàn)需要用到的接口方法
          ????????Operator?operator2?=?new?Operator();
          ????????operator2.addOperation(new?DefaultAdapter()?{
          ????????????@Override
          ????????????public?void?operation2()?{
          ????????????????System.out.println("invoke?operation2");
          ????????????}
          ????????});
          ????????operator2.operation2();
          ????}
          }

          適配器模式本質(zhì)上是現(xiàn)有的不兼容的接口轉(zhuǎn)換為需要的接口。類適配器模式以繼承現(xiàn)有類的方式轉(zhuǎn)換;對象適配器模式以聚合對象實(shí)例的方式轉(zhuǎn)換;接口適配器模式以實(shí)現(xiàn)接口的方式轉(zhuǎn)換。適配器模式是在現(xiàn)有的類和系統(tǒng)都不易修改的情況下才使用,在系統(tǒng)設(shè)計(jì)之初慎用該設(shè)計(jì)模式。

          掃碼二維碼

          獲取更多精彩

          Java樂園

          有用!分享+在看?
          瀏覽 44
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美操逼视频免费观看 | 国产一区在线视频 | 一级a做一级a做片性视频视频在线 | 精品国产乱码久久久久夜深人妻 | 日本处女学生妺一级片 |