1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        兩個(gè)對(duì)象不合適?——適配器模式

        共 4038字,需瀏覽 9分鐘

         ·

        2021-11-01 18:39

        設(shè)計(jì)模式專欄

        ?

        1、什么是適配器模式?

        Convert the interface of a class into another interface clients expect.Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.

        適配器模式(Adapter Pattern):將一個(gè)類的接口變換成客戶端所期待的另一種接口,從而使原本因接口不匹配而無法在一起工作的兩個(gè)類能夠在一起工作。

        說人話:這個(gè)模式就是用來做適配的,它將不兼容的接口轉(zhuǎn)換為可兼容的接口,讓原本由于接口不兼容而不能一起工作的類可以一起工作。比如現(xiàn)實(shí)生活中的例子, USB 轉(zhuǎn)接頭就充當(dāng)適配器,把兩種不兼容的接口,通過轉(zhuǎn)接變得可以一起工作。

        2、適配器模式定義

        c76f93425881eac54c34936e828be9d7.webp

        ①、Target目標(biāo)角色

        該角色定義把其他類轉(zhuǎn)換為何種接口, 也就是我們的期望接口, 例子中的IUserInfo接口就是目標(biāo)角色。

        ②、Adaptee源角色

        你想把誰轉(zhuǎn)換成目標(biāo)角色, 這個(gè)“誰”就是源角色, 它是已經(jīng)存在的、 運(yùn)行良好的類或?qū)ο螅?經(jīng)過適配器角色的包裝, 它會(huì)成為一個(gè)嶄新、 靚麗的角色。

        ③、Adapter適配器角色

        適配器模式的核心角色, 其他兩個(gè)角色都是已經(jīng)存在的角色, 而適配器角色是需要新建立的, 它的職責(zé)非常簡(jiǎn)單:把源角色轉(zhuǎn)換為目標(biāo)角色, 怎么轉(zhuǎn)換?通過繼承或是類關(guān)聯(lián)的方式。

        3、適配器模式通用代碼實(shí)現(xiàn)

        /**
        ?*?目標(biāo)角色
        ?*/

        public?interface?Target?{
        ????void?t1();
        ????void?t2();
        ????void?t3();
        }
        /**
        ?*?目標(biāo)角色實(shí)現(xiàn)類
        ?*/

        public?class?ConcreteTarget?implements?Target{

        ????@Override
        ????public?void?t1()?{
        ????????System.out.println("目標(biāo)角色?t1?方法");
        ????}

        ????@Override
        ????public?void?t2()?{
        ????????System.out.println("目標(biāo)角色?t2?方法");
        ????}

        ????@Override
        ????public?void?t3()?{
        ????????System.out.println("目標(biāo)角色?t3?方法");
        ????}
        }
        /**
        ?*?源角色:要把源角色轉(zhuǎn)換成目標(biāo)角色
        ?*/

        public?class?Adaptee?{

        ????public?void?a1(){
        ????????System.out.println("源角色?a1?方法");
        ????}

        ????public?void?a2(){
        ????????System.out.println("源角色?a2?方法");
        ????}

        ????public?void?a3(){
        ????????System.out.println("源角色?a3?方法");
        ????}
        }

        基于繼承的類適配器

        /**
        ?*?適配器角色
        ?*/

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

        ????@Override
        ????public?void?t1()?{
        ????????super.a1();
        ????}

        ????@Override
        ????public?void?t2()?{
        ????????super.a2();
        ????}

        ????@Override
        ????public?void?t3()?{
        ????????super.a3();
        ????}
        }

        基于組合的對(duì)象適配器

        public?class?AdapterCompose?implements?Target{

        ????private?Adaptee?adaptee;

        ????public?AdapterCompose(Adaptee?adaptee){
        ????????this.adaptee?=?adaptee;
        ????}
        ????@Override
        ????public?void?t1()?{
        ????????adaptee.a1();
        ????}

        ????@Override
        ????public?void?t2()?{
        ????????adaptee.a2();
        ????}

        ????@Override
        ????public?void?t3()?{
        ????????adaptee.a3();
        ????}
        }

        測(cè)試:

        public?class?AdapterClient?{

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

        ????????//?基于繼承?增加適配器業(yè)務(wù)邏輯
        ????????Target?target1?=?new?Adapter();
        ????????target1.t1();

        ????????//?基于組合?增加適配器業(yè)務(wù)邏輯
        ????????Target?target2?=?new?AdapterCompose(new?Adaptee());
        ????????target2.t1();
        ????}
        }

        打印結(jié)果:

        37bbbbd4bc55677324f79ec2053db37a.webp

        適配器模式有兩種實(shí)現(xiàn)方式:類適配器和對(duì)象適配器。其中,類適配器使用繼承關(guān)系來實(shí)現(xiàn),對(duì)象適配器使用組合關(guān)系來實(shí)現(xiàn)。在實(shí)際開發(fā)中,選擇的依據(jù)如下:

        ①、如果 Adaptee 接口并不多,那兩種實(shí)現(xiàn)方式都可以。

        ②、如果 Adaptee 接口很多,而且 Adaptee 和 ITarget 接口定義大部分都相同,那我們推薦使用類適配器,因?yàn)?Adaptor 復(fù)用父類 Adaptee 的接口,比起對(duì)象適配器的實(shí)現(xiàn)方式,Adaptor 的代碼量要少一些。

        ③、如果 Adaptee 接口很多,而且 Adaptee 和 ITarget 接口定義大部分都不相同,那我們推薦使用對(duì)象適配器,因?yàn)榻M合結(jié)構(gòu)相對(duì)于繼承更加靈活。

        4、適配器模式優(yōu)點(diǎn)

        ①、適配器模式可以讓兩個(gè)沒有任何關(guān)系的類在一起運(yùn)行, 只要適配器這個(gè)角色能夠搞定他們就成。

        ②、增加了類的透明性

        我們?cè)L問的Target目標(biāo)角色, 但是具體的實(shí)現(xiàn)都委托給了源角色, 而這些對(duì)高層次模塊是透明的, 也是它不需要關(guān)心的。

        ③、提高了類的復(fù)用度

        源角色在原有的系統(tǒng)中還是可以正常使用, 而在目標(biāo)角色中也可以充當(dāng)新的演員。

        ④、靈活性非常好

        適配器可以隨時(shí)去掉,而不會(huì)影響很多代碼。

        5、適配器模式應(yīng)用場(chǎng)景

        ①、修改已使用的接口

        某個(gè)已經(jīng)投產(chǎn)中的接口需要修改,這時(shí)候使用適配器最好。

        ②、統(tǒng)一多個(gè)類的接口設(shè)計(jì)

        比如對(duì)于敏感詞過濾,需要調(diào)用好幾個(gè)第三方接口,每個(gè)接口方法名,方法參數(shù)又不一樣,這時(shí)候使用適配器模式,將所有第三方的接口適配為統(tǒng)一的接口定義。

        ③、兼容老版本接口

        比如JDK1.0 中包含一個(gè)遍歷集合容器的類 Enumeration,JDK2.0 對(duì)這個(gè)類進(jìn)行了重構(gòu),將它改名為 Iterator 類,并且對(duì)它的代碼實(shí)現(xiàn)做了優(yōu)化。但是考慮到如果將 Enumeration 直接從 JDK2.0 中刪除,那使用 JDK1.0 的項(xiàng)目如果切換到 JDK2.0,代碼就會(huì)編譯不通過。為了避免這種情況的發(fā)生,我們必須把項(xiàng)目中所有使用到 Enumeration 的地方,都修改為使用 Iterator 才行。

        單獨(dú)一個(gè)項(xiàng)目做 Enumeration 到 Iterator 的替換,勉強(qiáng)還能接受。但是,使用 Java 開發(fā)的項(xiàng)目太多了,一次 JDK 的升級(jí),導(dǎo)致所有的項(xiàng)目不做代碼修改就會(huì)編譯報(bào)錯(cuò),這顯然是不合理的。這就是我們經(jīng)常所說的不兼容升級(jí)。為了做到兼容使用低版本 JDK 的老代碼,我們可以暫時(shí)保留 Enumeration 類,并將其實(shí)現(xiàn)替換為直接調(diào)用 Itertor。

        public?class?Collections?{
        ??public?static?Emueration?emumeration(final?Collection?c)?{
        ????return?new?Enumeration()?{
        ??????Iterator?i?=?c.iterator();
        ??????
        ??????public?boolean?hasMoreElments()?{
        ????????return?i.hashNext();
        ??????}
        ??????
        ??????public?Object?nextElement()?{
        ????????return?i.next():
        ??????}
        ????}
        ??}
        }

        ④、適配不同格式的數(shù)據(jù)

        6、代理-橋接-裝飾器-適配器區(qū)別

        ①、代理模式在不改變?cè)碱惤涌诘臈l件下,為原始類定義一個(gè)代理類,主要目的是控制訪問,而非加強(qiáng)功能,這是它跟裝飾器模式最大的不同。

        ②、橋接模式:橋接模式的目的是將接口部分和實(shí)現(xiàn)部分分離,從而讓它們可以較為容易、也相對(duì)獨(dú)立地加以改變。

        ③、裝飾器模式:裝飾者模式在不改變?cè)碱惤涌诘那闆r下,對(duì)原始類功能進(jìn)行增強(qiáng),并且支持多個(gè)裝飾器的嵌套使用。

        ④、適配器模式:適配器模式是一種事后的補(bǔ)救策略。適配器提供跟原始類不同的接口,而代理模式、裝飾器模式提供的都是跟原始類相同的接口。

        關(guān)于我

        可樂是一個(gè)熱愛技術(shù)的Java程序猿,公眾號(hào)「IT可樂」定期分享有趣有料的精品原創(chuàng)文章!

        812449625aa5af32ec14f8af643b61d4.webp

        非常感謝各位人才能看到這里,原創(chuàng)不易,文章如果有幫助可以關(guān)注、點(diǎn)贊、分享或評(píng)論,這都是對(duì)我的莫大支持!

        愿你我人生盡量沒有遺憾的事,愿你我都能奔赴在各自想去的路上。


        瀏覽 51
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

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

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            国产精品色婷婷7777777 | 成人国产精品秘 免费观看 | 欧美另类视频一区 | 日韩无码性生活视频 | 午夜久久网| 日逼网站免费 | 六月婷婷五月天 | 8x人成免费入口 milky牝教师~淫辱の教室 | 国产搞鸡巴 | 国产区精品视频 |