設計模式之介面卡模式(adaptor pattern)
阿新 • • 發佈:2019-01-06
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. 增加了類的透明度。
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進行工作。
執行結果:
接通電源,開始工作......
開始做飯......