07 介面卡模式(Adapter Pattern)
概念相關
定義:
介面卡模式把一個類的介面變換成客戶端所期待的另一種介面,從而 使原本因介面不匹配而無法在一起工作的兩個類能夠在一起工作。
簡單點說:
兩個彼此間沒有太大關聯的類,想進行互動完成某些事情,如果 直接去修改各自的介面,就顯得有些繁瑣了,可以加個中間類, 用它來協調兩類之間的關係,完成相關業務。這種玩法就叫介面卡模式!
兩種介面卡模式:
根據介面卡類與適配者類的關係不同,介面卡模式可分為 類介面卡 和 物件介面卡兩種,儘管都是三個角色,但還是有些差別的! 另外,類介面卡的介面卡和適配者是繼承關係,而物件介面卡則是引用關係。
類介面卡的三個角色:
- 目標介面(Target):客戶所期待的介面,目標是介面;
- 需要適配的類(Adaptee):需要適配的類或適配者類;
- 介面卡(Adapter):實現了抽象目標類介面Target,並繼承了適配者類Adaptee
物件介面卡的三個角色:
- 目標介面(Target):客戶所期待的介面,可以是具體的或抽象的類,也可以是介面
- 需要適配的類(Adaptee):需要適配的類或適配者類;
- 介面卡(Adapter):通過包裝一個需要適配的物件,把原介面轉換成目標介面;
UML類圖:
類介面卡圖:
物件介面卡圖:
示例程式碼
package structPattrn.adapterPattern; /** * 介面卡模式測試例程 * 介面卡模式把一個類的介面變換成客戶端所期待的另一種介面,從而使原本因介面不匹配而無法在一起工作的兩個類能夠在一起工作。 * 根據介面卡類與適配者類的關係不同,介面卡模式可分為 類介面卡 和物件介面卡兩種,儘管都是三個角色,但還是有些差別的! * 另外,類介面卡的介面卡和適配者是 繼承 關係,而物件適 配器則是 引用 關係。 * @Package structPattrn.adapterPattern * @Title: AdapterPattern.java * @Company: $ * @author BurgessLee * @date 2018年10月16日-下午3:26:09 * @Description: $ */ public class AdapterPatternDemo { public static void main(String[] args) { //物件介面卡測試程式碼 Chinese chinese = new Translator(new English()); chinese.speakChinese("那你很厲害"); //物件介面卡測試程式碼 ClassTranslator classTranslator = new ClassTranslator(); classTranslator.speakChinese("你也很厲害 --- 類介面卡"); } } interface Chinese{ public void speakChinese(String string); } //以下三個類是物件介面卡的舉例 class English{ public void speakEnglish(String string){ System.out.println("【英語】"+ string); } } class Translator implements Chinese{ private English english = new English(); public Translator(English english) { super(); this.english = english; } @Override public void speakChinese(String string) { english.speakEnglish(string); } } //類介面卡舉例如下: class ClassTranslator extends English implements Chinese{ @Override public void speakChinese(String string) { speakEnglish(string); } }
列印結果:
【英語】那你很厲害
【英語】你也很厲害 --- 類介面卡
兩種玩法對比
物件介面卡支援傳入一個被介面卡物件,因此可以做到對多種被適 配介面進行適配。而類介面卡直接繼承,無法動態修改,所以一般情況 下物件介面卡使用得更多!(Java不支援多重繼承!!!)
預設介面卡模式
當不需要實現一個介面所提供的所有方法時,可先設計一個抽象類 實現該介面,併為介面中每個方法提供一個預設實現(空方法), 那麼該抽象類的子類可以選擇性地覆蓋父類的某些方法來實現需求, 它適用於不想使用一個介面中的所有方法的情況,又稱為單介面介面卡模式。
簡單點說就是:不想實現接口裡的所有方法,寫個基類去繼承這個介面,然後重寫所有方法,子類再去繼承這個基類,按需重寫!比如上面的例子,中文也有很多種型別啊,普通話,廣東話,上海話: 我們現在只需要轉換成普通話:
程式碼如下:
//預設介面卡模式
interface ChineseTarget{
void speakChinese(String string);//普通話
void speakContones(String string);//廣東話
void speakShanghainese(String string);//上海話
}
class BaseAdapter implements ChineseTarget{
@Override
public void speakChinese(String string) {
}
@Override
public void speakContones(String string) {
}
@Override
public void speakShanghainese(String string) {
}
}
class ChineseAdapter extends BaseAdapter{
private English english;
public ChineseAdapter(English english) {
super();
this.english = english;
}
@Override
public void speakChinese(String string) {
this.english.speakEnglish(string);
}
}
測試如下:
//預設介面卡適配模式
BaseAdapter baseAdapter = new ChineseAdapter(new English());
baseAdapter.speakChinese("預設介面卡模式");
優點
將目標類和適配者類解耦,通過引入一個介面卡類來重用現有的適配者類,無須修改原有結構。
增加了類的透明性和複用性,將具體的業務實現過程封裝在適配者類中,對於客戶端類而言是透明的,而且提高了適配者的複用, 同一個適配者類可以在多個不同的系統中複用。
靈活性和擴充套件性都非常好,可以很方便地更換介面卡。一個物件介面卡可以把多個不同的適配者適配到同一個目標。
缺點
類介面卡模式對於不支援多重類繼承的語言,一次最多隻能適配 一個適配者類,不能同時適配多個適配者。適配者類不能為最終類,如在Java中不能為final類。在Java中,類介面卡模式中的目標抽象類只能為介面,不能為類, 其使用有一定的侷限性。物件介面卡要在介面卡中置換適配者類的某些方法比較麻煩。