Adapter 介面卡模式(設計模式03)

衣舞晨風發表於2016-06-07

疑問:

  • 在軟體系統中,由於應用環境的變化,常常需要將“一些現存的物件”放在新的環境中應用,但是新環境要求的介面是這些現存物件所不滿足的。 如何應對這種“遷移的變化”?
  • 如何既能利用現有物件的良好實現,同時又能滿足新的應用環境所要求的介面?

定義:

將一個類的介面轉換成客戶希望的另一個介面。Adapter模式使得原本由於介面不相容而不能一起工作的那些類可以一起工作。
——《設計模式》GoF

一、物件介面卡

物件介面卡採用物件組合,通過引用一個類與另一個類介面 在物件介面卡中通過組合獲得Adaptee物件 通過呼叫Adaptee物件的方法,轉換後返回Target結果。

這裡寫圖片描述

這裡寫圖片描述

二、類介面卡

類介面卡通過多繼承對一個介面與另一個介面進行匹配。
Target定義了Client使用的與特定領域相關的介面,Client通過呼叫Target實現某一個特定的操作。Adaptee是一個已經存在的類,需要與Target協同工作,這個介面需要適配。Adapter介面卡適配Adaptee和Target介面。在類介面卡中,通過繼承獲得Adaptee中的方法。

.NET不支援多重繼承,因此當Target是一個類,而不是一個介面時無法實現類介面卡,這時需要使用物件介面卡。

這裡寫圖片描述

三、生活中的例子

在國內使用的電源供電電壓為220V,美國為380V,當你出差到美國,你的電器需要220V的電壓,但旅館裡不提供220V,只提供380,所以,你到市場買了一個電源介面卡,在接上介面卡後,旅館裡的電源就可以使用在你的電器上了。

Target:標準電源
Adaptee:美國電源
Adapter:介面卡

1、實現-Target

 /// <summary>
    /// 目標:Target
    /// </summary>
    public class StandardPower
    {
        /// <summary>
        /// 供電
        /// </summary>
        /// <returns></returns>
        public virtual int SupplyPower()
        {
            Console.Write("正常SupplyPower,電壓:");
            return 220;
        }
    }

2、實現-Adaptee

 /// <summary>
    /// 要適配的物件:Adaptee
    /// </summary>
    public class AmericanPower
    {
        public int SupplyPower()
        {
            Console.Write("在美國供給380V電壓");
            return 380;
        }
    }

3、實現-Adapter

 /// <summary>
    /// 介面卡:Adapter
    /// </summary>
    public class PowerAdapter : StandardPower
    {
        /// <summary>
        /// 當地電源
        /// </summary>
        private AmericanPower localPower = new AmericanPower();
        public override int SupplyPower()
        {
            int v = localPower.SupplyPower();
            if (v != 220)
            {
                //這裡做一些轉換工作                
                v = 220;
            }
            Console.WriteLine("轉換後的電壓:{0}", v.ToString());
            return v;//轉換後,即適配後
        }
    }

4、實現-使用

 StandardPower power = null;

            //在中國的時候
            power = new StandardPower();
            Console.WriteLine(power.SupplyPower());

            //到美國以後,買一個介面卡
            power = new PowerAdapter();
            Console.WriteLine("適配後提SupplyPower源電壓為:{0}", power.SupplyPower());

            //讓控制檯 等待
            Console.ReadLine();

四、.NET中的Adapter模式

1.介面卡模式在.NET Framework中的一個最大的應用就是COM Interop。

COM Interop就好像是COM和.NET之間的一座橋樑(關於COM互操作更多內容可以參考我的互操作系列)。COM元件物件與.NET類物件是完全不同的,但為了使.NET程式
象使用.NET物件一樣使用COM元件,微軟在處理方式上採用了Adapter模式,對COM物件進行包裝,這個包裝類就是RCW(Runtime Callable Wrapper)。RCW實際上是runtime生成的一個.NET類,它包裝了COM元件的方法,並內部實現對COM元件的呼叫。如下圖所示:
這裡寫圖片描述

2..NET中的另外一個介面卡模式的應用就是DataAdapter。

ADO.NET為統一的資料訪問提供了多個介面和基類,其中最重要的介面之一是IdataAdapter。DataAdpter起到了資料庫到DataSet橋接器的作用,使應用程式的資料操作統一到DataSet上,而與具體的資料庫型別無關。甚至可以針對特殊的資料來源編制自己的DataAdpter,從而使我們的應用程式與這些特殊的資料來源相相容。

五、實現要點

介面卡模式重在轉換介面,它能夠使原本不能在一起工作的兩個類一起工作,所以經常用在類庫複用,程式碼遷移等方面,有一種亡羊補牢的味道

類介面卡和物件介面卡可以根據具體實際情況來選用,但一般情況建議使用物件介面卡模式

六、效果

通過類的繼承或者物件的組合轉換已有的介面為目標介面

七、適用性

需要使用一個已經存在的類,但介面與設計要求不符。

希望建立一個可以複用的類,該類可以與其他不相關的類或者是將來不可預見的類協同工作。

八、總結

Adapter模式主要應用於“希望複用一些現存的類,但是介面又與複用環境要求不一致的情況” ,在遺留程式碼複用、類庫遷移等方面非常有用。

GoF 23 定義了兩種Adapter模式的實現結構:物件介面卡和類介面卡。但類介面卡採用“多繼承”的實現方式,帶來了不良的高耦合,所以一般不推薦使用。物件介面卡採用“物件組合”的方式,更符合鬆耦合精神。

Adapter模式可以實現的非常靈活,不必拘泥於Gof23中定義的兩種結構。例如,完全可以將Adapter模式中的“現存物件”作為新的介面方法引數,來達到適配的目的。

Adapter模式本身要求我們儘可能地使用“面向介面的程式設計”風格,這樣才能在後期很方便地適配。

作者:jiankunking 出處:http://blog.csdn.net/jiankunking

原始碼下載:http://download.csdn.net/detail/xunzaosiyecao/9543274
小注:
本文部分資料整理自網路,在此表示感謝。
1、 C#設計模式(7)——介面卡模式(Adapter Pattern)

2、本傑.NET 張波的PPT資料

相關文章