<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                [TOC] 轉:https://www.cnblogs.com/java-my-life/archive/2012/04/13/2442795.html # 1.基礎概念 1. **適配器模式把一個類的接口變換成客戶端所期待的另一種接口,從而使原本因接口不匹配而無法在一起工作的兩個類能夠在一起工作。** 2. 適配器模式有**類的適配器模式**和**對象的適配器模式**兩種不同的形式。 用電器做例子,筆記本電腦的插頭一般都是三相的,即除了陽極、陰極外,還有一個地極。而有些地方的電源插座卻只有兩極,沒有地極。電源插座與筆記本電腦的電源插頭不匹配使得筆記本電腦無法使用。這時候一個三相到兩相的轉換器(適配器)就能解決此問題,而這正像是本模式所做的事情。 ## 1.1 類適配器模式 類的適配器模式把適配的類的API轉換成為目標類的API。 ![](https://box.kancloud.cn/6a2c4c86c6c87367a5d8e3e55c9da9d2_854x303.png) 在上圖中可以看出,Adaptee類并沒有sampleOperation2()方法,而客戶端則期待這個方法。為使客戶端能夠使用Adaptee類,提供一個中間環節,即類Adapter,把Adaptee的API與Target類的API銜接起來。Adapter與Adaptee是繼承關系,這決定了這個適配器模式是類的: > 1. 目標(Target)角色: > 這就是所期待得到的接口。注意:由于這里討論的是類適配器模式,因此目標不可以是類。 > 2. .源(Adapee)角色: > 現在需要適配的接口。 > 3. 適配器(Adaper)角色: > 適配器類是本模式的核心。適配器把源接口轉換成目標接口。顯然,這一角色不可以是接口,而必須是具體類。 例子: ``` public interface Target { /** * 這是源類Adaptee也有的方法 */ public void sampleOperation1(); /** * 這是源類Adapteee沒有的方法 */ public void sampleOperation2(); } ``` 上面給出的是目標角色的源代碼,這個角色是以一個JAVA接口的形式實現的。可以看出,這個接口聲明了兩個方法:sampleOperation1()和sampleOperation2()。而源角色Adaptee是一個具體類,它有一個sampleOperation1()方法,但是沒有sampleOperation2()方法。 ``` public class Adaptee { public void sampleOperation1(){} } ``` 適配器角色Adapter擴展了Adaptee,同時又實現了目標(Target)接口。由于Adaptee沒有提供sampleOperation2()方法,而目標接口又要求這個方法,因此適配器角色Adapter實現了這個方法。 ``` public class Adapter extends Adaptee implements Target { /** * 由于源類Adaptee沒有方法sampleOperation2() * 因此適配器補充上這個方法 */ @Override public void sampleOperation2() { //寫相關的代碼 } } ``` ## 1.2對象適配器模式   與類的適配器模式一樣,對象的適配器模式把被適配的類的API轉換成為目標類的API,與類的適配器模式不同的是,對象的適配器模式不是使用繼承關系連接到Adaptee類,而是使用委派關系連接到Adaptee類。 ![](https://box.kancloud.cn/60f4f22cad401085349ebdeff328d595_637x329.png)   從上圖可以看出,Adaptee類并沒有sampleOperation2()方法,而客戶端則期待這個方法。為使客戶端能夠使用Adaptee類,需要提供一個包裝(Wrapper)類Adapter。這個包裝類包裝了一個Adaptee的實例,從而此包裝類能夠把Adaptee的API與Target類的API銜接起來。Adapter與Adaptee是委派關系,這決定了適配器模式是對象的。 ``` public interface Target { /** * 這是源類Adaptee也有的方法 */ public void sampleOperation1(); /** * 這是源類Adapteee沒有的方法 */ public void sampleOperation2(); } ``` ~~~ public class Adaptee { public void sampleOperation1(){} } ~~~ [![復制代碼](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "復制代碼") [![復制代碼](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "復制代碼") ~~~ public class Adapter { private Adaptee adaptee; public Adapter(Adaptee adaptee){ this.adaptee = adaptee; } /** * 源類Adaptee有方法sampleOperation1 * 因此適配器類直接委派即可 */ public void sampleOperation1(){ this.adaptee.sampleOperation1(); } /** * 源類Adaptee沒有方法sampleOperation2 * 因此由適配器類需要補充此方法 */ public void sampleOperation2(){ //寫相關的代碼 } } ~~~ [![復制代碼](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "復制代碼") ### 類適配器和對象適配器的權衡   ●  **類適配器**使用對象繼承的方式,是靜態的定義方式;而**對象適配器**使用對象組合的方式,是動態組合的方式。   ●  **對于類適配器**,由于適配器直接繼承了Adaptee,使得適配器不能和Adaptee的子類一起工作,因為繼承是靜態的關系,當適配器繼承了Adaptee后,就不可能再去處理? Adaptee的子類了。      **對于對象適配器**,一個適配器可以把多種不同的源適配到同一個目標。換言之,同一個適配器可以把源類和它的子類都適配到目標接口。因為對象適配器采用的是對象組合的關系,只要對象類型正確,是不是子類都無所謂。   ● ? **對于類適配器**,適配器可以重定義Adaptee的部分行為,相當于子類覆蓋父類的部分實現方法。      **對于對象適配器**,要重定義Adaptee的行為比較困難,這種情況下,需要定義Adaptee的子類來實現重定義,然后讓適配器組合子類。雖然重定義Adaptee的行為比較困難,但是想要增加一些新的行為則方便的很,而且新增加的行為可同時適用于所有的源。   ●  **對于類適配器**,僅僅引入了一個對象,并不需要額外的引用來間接得到Adaptee。      **對于對象適配器**,需要額外的引用來間接得到Adaptee。   建議盡量使用對象適配器的實現方式,多用合成/聚合、少用繼承。當然,具體問題具體分析,根據需要來選用實現方式,最適合的才是最好的。 ## 適配器模式的優點 * **  更好的復用性**   系統需要使用現有的類,而此類的接口不符合系統的需要。那么通過適配器模式就可以讓這些功能得到更好的復用。 * **  更好的擴展性**   在實現適配器功能的時候,可以調用自己開發的功能,從而自然地擴展系統的功能。 ## 適配器模式的缺點   過多的使用適配器,會讓系統非常零亂,不易整體進行把握。比如,明明看到調用的是A接口,其實內部被適配成了B接口的實現,一個系統如果太多出現這種情況,無異于一場災難。因此如果不是很有必要,可以不使用適配器,而是直接對系統進行重構。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看