1. 程式人生 > >【設計模式最終總結】介面卡模式

【設計模式最終總結】介面卡模式

什麼是介面卡

我的膝上型電腦的工作電壓是20V,而我國的家庭用電是220V,如何讓20V的膝上型電腦能夠在220V的電壓下工作?答案是引入一個電源介面卡(AC Adapter),俗稱充電器或變壓器,有了這個電源介面卡,生活用電和膝上型電腦即可相容。

在軟體開發中,有時也存在類似這種不相容的情況,我們也可以像引入一個電源介面卡一樣引入一個稱之為介面卡的角色來協調這些存在不相容的結構,這種設計方案即為介面卡模式。

介面卡模式概述

介面卡模式(Adapter Pattern):將一個介面轉換成客戶希望的另一個介面,使介面不相容的那些類可以一起工作,其別名為包裝器(Wrapper)。介面卡模式既可以作為類結構型模式,也可以作為物件結構型模式。

在物件介面卡模式中,介面卡與適配者之間是關聯關係;在類介面卡模式中,介面卡與適配者之間是繼承(或實現)關係。

物件介面卡

       在物件介面卡模式結構圖中包含如下幾個角色:

       ● Target(目標抽象類):目標抽象類定義客戶所需介面,可以是一個抽象類或介面,也可以是具體類。

       ● Adapter(介面卡類):介面卡可以呼叫另一個介面,作為一個轉換器,對Adaptee和Target進行適配,介面卡類是介面卡模式的核心,在物件介面卡中,它通過繼承Target並關聯一個Adaptee物件使二者產生聯絡。

       ● Adaptee(適配者類):適配者即被適配的角色,它定義了一個已經存在的介面,這個介面需要適配,適配者類一般是一個具體類,包含了客戶希望使用的業務方法,在某些情況下可能沒有適配者類的原始碼。

類介面卡

 類介面卡模式和物件介面卡模式最大的區別在於介面卡和適配者之間的關係不同,物件介面卡模式中介面卡和適配者之間是關聯關係,而類介面卡模式中介面卡和適配者是繼承關係

預設介面卡  

預設介面卡模式(Default Adapter Pattern):當不需要實現一個介面所提供的所有方法時,可先設計一個抽象類實現該介面,併為介面中每個方法提供一個預設實現(空方法),那麼該抽象類的子類可以選擇性地覆蓋父類的某些方法來實現需求,它適用於不想使用一個介面中的所有方法的情況,又稱為單介面介面卡模式。

在預設介面卡模式中,包含如下三個角色:

      ● ServiceInterface(適配者介面):它是一個介面,通常在該介面中聲明瞭大量的方法。

      ● AbstractServiceClass(預設介面卡類):它是預設介面卡模式的核心類,使用空方法的形式實現了在ServiceInterface介面中宣告的方法。通常將它定義為抽象類,因為對它進行例項化沒有任何意義。

      ● ConcreteServiceClass(具體業務類):它是預設介面卡類的子類,在沒有引入介面卡之前,它需要實現適配者介面,因此需要實現在適配者介面中定義的所有方法,而對於一些無須使用的方法也不得不提供空實現。在有了預設介面卡之後,可以直接繼承該介面卡類,根據需要有選擇性地覆蓋在介面卡類中定義的方法。

       在JDK類庫的事件處理包java.awt.event中廣泛使用了預設介面卡模式,如WindowAdapter、KeyAdapter、MouseAdapter等。下面我們以處理視窗事件為例來進行說明:在Java語言中,一般我們可以使用兩種方式來實現視窗事件處理類,一種是通過實現WindowListener介面,另一種是通過繼承WindowAdapter介面卡類。如果是使用第一種方式,直接實現WindowListener介面,事件處理類需要實現在該介面中定義的七個方法,而對於大部分需求可能只需要實現一兩個方法,其他方法都無須實現,但由於語言特性我們不得不為其他方法也提供一個簡單的實現(通常是空實現),這給使用帶來了麻煩。而使用預設介面卡模式就可以很好地解決這一問題,在JDK中提供了一個介面卡類WindowAdapter來實現WindowListener介面,該介面卡類為介面中的每一個方法都提供了一個空實現,此時事件處理類可以繼承WindowAdapter類,而無須再為介面中的每個方法都提供實現。

 

介面卡模式總結  

    介面卡模式將現有介面轉化為客戶類所期望的介面,實現了對現有類的複用,它是一種使用頻率非常高的設計模式,在軟體開發中得以廣泛應用,在Spring等開源框架、驅動程式設計(如JDBC中的資料庫驅動程式)中也使用了介面卡模式。

 

       1. 主要優點

       無論是物件介面卡模式還是類介面卡模式都具有如下優點:

       (1) 將目標類和適配者類解耦,通過引入一個介面卡類來重用現有的適配者類,無須修改原有結構。

       (2) 增加了類的透明性和複用性,將具體的業務實現過程封裝在適配者類中,對於客戶端類而言是透明的,而且提高了適配者的複用性,同一個適配者類可以在多個不同的系統中複用。

       (3) 靈活性和擴充套件性都非常好,通過使用配置檔案,可以很方便地更換介面卡,也可以在不修改原有程式碼的基礎上增加新的介面卡類,完全符合“開閉原則”。

      具體來說,類介面卡模式還有如下優點:

      由於介面卡類是適配者類的子類,因此可以在介面卡類中置換一些適配者的方法,使得介面卡的靈活性更強。

      物件介面卡模式還有如下優點:

      (1) 一個物件介面卡可以把多個不同的適配者適配到同一個目標;

      (2) 可以適配一個適配者的子類,由於介面卡和適配者之間是關聯關係,根據“里氏代換原則”,適配者的子類也可通過該介面卡進行適配。

 

      2. 主要缺點

     類介面卡模式的缺點如下:

      (1) 對於Java、C#等不支援多重類繼承的語言,一次最多隻能適配一個適配者類,不能同時適配多個適配者;

      (2) 適配者類不能為最終類,如在Java中不能為final類,C#中不能為sealed類;

      (3) 在Java、C#等語言中,類介面卡模式中的目標抽象類只能為介面,不能為類,其使用有一定的侷限性。

      物件介面卡模式的缺點如下:

      與類介面卡模式相比,要在介面卡中置換適配者類的某些方法比較麻煩。如果一定要置換掉適配者類的一個或多個方法,可以先做一個適配者類的子類,將適配者類的方法置換掉,然後再把適配者類的子類當做真正的適配者進行適配,實現過程較為複雜。

 

      3. 適用場景

      在以下情況下可以考慮使用介面卡模式:

       (1) 系統需要使用一些現有的類,而這些類的介面(如方法名)不符合系統的需要,甚至沒有這些類的原始碼。

       (2) 想建立一個可以重複使用的類,用於與一些彼此之間沒有太大關聯的一些類,包括一些可能在將來引進的類一起工作。