1. 程式人生 > >設計模式之介面卡模式(adaptor pattern)

設計模式之介面卡模式(adaptor pattern)

1 介面卡模式的定義

在設計模式中,介面卡模式(英語:adapter pattern)有時候也稱包裝樣式或者包裝(wrapper)。將一個類的介面轉接成使用者所期待的。一個適配使得因介面不相容而不能在一起工作的類工作在一起,做法是將類自己的介面包裹在一個已存在的類中。

2 實際應用中的例子

  • 比如我們去日本買了一個日本的電飯煲,但日本電壓標準都是110V,而我們國家標準是220V,所以要想在中國用日本電飯煲,需要一個電源介面卡。
  • 比如我們有一個micro SD卡,如果我們想在筆記本上用,就需要一個讀卡器做為介面卡
  • JAVA JDK 1.1 提供了 Enumeration 介面,而在 1.2 中提供了 Iterator 介面,想要使用 1.2 的 JDK,則要將以前系統的 Enumeration 介面轉化為 Iterator 介面,這時就需要介面卡模式。
  • JAVA 中的 jdbc。

3 應用場景

  1. 系統需要使用現有的類,而此類的介面不符合系統的需要。
  2. 想要建立一個可以重複使用的類,用於與一些彼此之間沒有太大關聯的一些類,包括一些可能在將來引進的類一起工作,這些源類不一定有一致的介面。
  3. 通過介面轉換,將一個類插入另一個類系中。(比如老虎和飛禽,現在多了一個飛虎,在不增加實體的需求下,增加一個介面卡,在裡面包容一個虎物件,實現飛的介面。)

優點:
1. 可以讓任何兩個沒有關聯的類一起執行。
2. 提高了類的複用。
3. 增加了類的透明度。
4. 靈活性好。
缺點:
1. 過多地使用介面卡,會讓系統非常零亂,不易整體進行把握。比如,明明看到呼叫的是 A 介面,其實內部被適配成了 B 介面的實現,一個系統如果太多出現這種情況,無異於一場災難。因此如果不是很有必要,可以不使用介面卡,而是直接對系統進行重構。
2. 由於 JAVA 至多繼承一個類,所以至多隻能適配一個適配者類,而且目標類必須是抽象類。

4 介面卡模式角色

這裡寫圖片描述

5 舉例說明

我們就拿日本電飯煲的例子進行說明,日本電飯煲電源介面標準是110V電壓,而中國標準電壓介面是220V,所以要想在中國用日本電飯煲,需要一個電源轉換器。

5.1 定義日本和中國兩種介面及其實現

我們先定義日本220V電源介面和實現。

110V介面:

/**
 * 日本110V電源介面
 * */
public interface JP110VInterface {
   public void connect();
}

110V介面實現:

public class JP110VInterfaceImpl implements JP110VInterface {
   public void connect() {
      System.out.println("接通電源,開始工作....");
   }
}

我們再定義中國220V電源介面和實現。

220V介面:

public interface CN220VInterface {
   public void connect();
}

220V介面實現:

public class CN220VInterfaceImpl implements CN220VInterface {
   public void connect() {
      System.out.println("接通電源,開始工作......");
   }
}

5.2 定義一個電壓介面卡

要想在中國使用日本電飯煲,需要把電飯煲110v的電源介面適配成我們220V的電源介面,這就需要一個電源介面卡:

/**
 * 為了能夠適配定電飯煲110v電源介面,我們需要繼承110v介面
 * */
public class PowerAdaptor implements JP110VInterface {
   private CN220VInterface cn220VInterface;//用220V介面進行適配
   PowerAdaptor(CN220VInterface cn220VInterface){
      this.cn220VInterface=cn220VInterface;
   }
   public void connect() {
      cn220VInterface.connect();
   }
}

介面卡繼承的是要適配的介面,並持有對客戶的介面的引用。

5.3 電飯煲

下面正式開始啦,現在我們有一個日本電飯煲,用的是110v的電源介面:

public class ElectricCooker {
   private JP110VInterface jp110VInterface;//日本電飯煲,用的是日本110V標準電源介面
   ElectricCooker(JP110VInterface jp110VInterface){
      this.jp110VInterface=jp110VInterface;
   }
   public void cook(){
      jp110VInterface.connect();//接通電源
      System.out.println("開始做飯......");
   }
}

電飯煲用的是110V介面

5.4 電飯煲配合介面卡工作

測試類:

public class AdaptorTest {
   public static void main(String[] args) {
       CN220VInterface cn220VInterface=new CN220VInterfaceImpl();//中國的220V電源
       PowerAdaptor adaptor=new PowerAdaptor(cn220VInterface);//電源介面卡
       ElectricCooker cooker=new ElectricCooker(adaptor);//使用110V介面的電飯煲
       cooker.cook();//使用了介面卡,在220V的環境下可以工作啦
   }
}

介面卡繼承了110V介面,就可以用於日本電飯煲;介面卡又持有220V介面的引用,就可以用220V進行工作。

執行結果:

接通電源,開始工作......
開始做飯......