設計模式之適配器模式

1 概述

  適配器模式(Adapter),說白了就是爲了掛羊頭賣狗肉而專門設計的模式。也就是把一個類的接口變換成客戶端所期待的另一種接口。

  適配器模式通過定義一個新的接口(對要實現的功能加以抽象),和一個實現該接口的Adapter(適配器)類來透明地調用外部組件。這樣替換外部組件時,最多隻要修改幾個Adapter類就可以了,其他源代碼都不會受到影響。

     還是以手機爲例子,每一種機型都自帶有從電器,有一天自帶充電器壞了,而且市場沒有這類型充電器可買了,怎麼辦?萬能充電器就可以解決,這個萬能充電器就是適配器。

     適配器模式有兩種形式,一種是類的適配,另一種自然就是對象的適配。

1.1 類的適配

    這種適配方式,由以下幾個角色組成:

(1)目標(Target)角色:這就是所期待得到的接口。注意:由於這裏討論的是類適配器模式,因此目標不可以是類。

(2)源(Adapee)角色:現在需要適配的接口。

(3)適配器(Adaper)角色:適配器類是本模式的核心。適配器把源接口轉換成目標接口。顯然,這一角色不可以是接口,而必須是具體類。

1.2 對象的適配

  對象的適配依賴於對象的組合,而不是類適配中的繼承。

     直接上例子來說明更容易理解。

2 示例

    首先來一個IPhone的充電器類(Adaptee角色):

 1 package org.scott.adapter;
 2 /** 
 3  * @author Scott
 4  * @date 2013-11-23 
 5  * @description
 6  */
 7 public class IPhoneCharger {
 8     public void applePhoneCharge(){
 9         System.out.println("The iPhone is charging ...");
10     }
11 }


現在,要對這個特殊的充電器進行適配,上個適配的接口(Target角色)

1 package org.scott.adapter;
2 /** 
3  * @author Scott
4  * @date 2013-11-23 
5  * @description
6  */
7 public interface ChargeAdapter {
8     public void phoneCharge();
9 }


因爲適配有兩種,所以先進行類的適配示例,創建類的適配器

 1 package org.scott.adapterclass;
 2 
 3 import org.scott.adapter.ChargeAdapter;
 4 import org.scott.adapter.IPhoneCharger;
 5 
 6 /** 
 7  * @author Scott
 8  * @date 2013-11-23 
 9  * @description
10  */
11 public class UniversalCharger extends IPhoneCharger implements ChargeAdapter{
12 
13     @Override
14     public void phoneCharge() {
15         System.out.println("The phone is charging, but which kind of phone it is, who cares ...");
16         
17         //iphone charging
18         super.applePhoneCharge();
19     }
20     
21 }

這就是萬能充電器了,我們讓它來充個電,測試類準備:

 1 package org.scott.adapterclass;
 2 
 3 import org.scott.adapter.ChargeAdapter;
 4 
 5 /** 
 6  * @author Scott
 7  * @date 2013-11-23 
 8  * @description
 9  */
10 public class AdapterClassTest {
11 
12     public static void main(String[] args) {
13         ChargeAdapter charger = new UniversalCharger();
14         charger.phoneCharge();
15     }
16 
17 }


充電結果:

The phone is charging, but which kind of phone it is, who cares ...
The iPhone is charging ...


ok,以上是類的適配,我們還有種對象的適配方式,創建對象的適配器

 1 package org.scott.adapterobject;
 2 
 3 import org.scott.adapter.ChargeAdapter;
 4 import org.scott.adapter.IPhoneCharger;
 5 
 6 /** 
 7  * @author Scott
 8  * @date 2013-11-23 
 9  * @description
10  */
11 public class UniversalCharger implements ChargeAdapter{
12     IPhoneCharger iphoneCharger;
13     
14     public UniversalCharger(IPhoneCharger iphoneCharger){
15         this.iphoneCharger = iphoneCharger;
16     }
17     
18     @Override
19     public void phoneCharge() {
20         System.out.println("The phone is charging, but which kind of phone it is, who cares ...");
21         iphoneCharger.applePhoneCharge();    
22     }
23 
24 
25 }


新一代對象適配器創建完畢,測一把:

 1 package org.scott.adapterobject;
 2 
 3 import org.scott.adapter.ChargeAdapter;
 4 import org.scott.adapter.IPhoneCharger;
 5 
 6 /** 
 7  * @author Scott
 8  * @date 2013-11-23 
 9  * @description
10  */
11 public class AdapterObjectTest {
12 
13     public static void main(String[] args) {
14         IPhoneCharger iphoneCharger = new IPhoneCharger();
15         ChargeAdapter charger = new UniversalCharger(iphoneCharger);
16         charger.phoneCharge();
17     }
18 
19 }


運行結果:

The phone is charging, but which kind of phone it is, who cares ...
The iPhone is charging ...


ok,目的也達到了。

  小節一下。

(1)類的適配器模式:當希望將一個類轉換成滿足另一個新接口的類時,可以使用類的適配器模式,創建一個新類,繼承原有的類,實現新的接口即可。

(2)對象的適配器模式:當希望將一個對象轉換成滿足另一個新接口的對象時,可以創建一個包裝類,持有原類的一個實例,在包裝類的方法中,調用實例的方法就行。

  自然,最後還是要來個UML圖(源自網絡):

類適配:

對象適配:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章