日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

設計模式學習筆記(七)——Adapter適配器模式

 skywood 2007-08-06

       Adapter適配器模式是一種結(jié)構(gòu)型模式,主要應對:由于應用環(huán)境的變化,常常需要將“一些現(xiàn)存的對象”放在新的環(huán)境中應用,但是,新環(huán)境要求的接口是現(xiàn)存對象所不滿足的。

       《設計模式》中說道:將一個類的接口轉(zhuǎn)換成客戶希望的另一個接口。Adapter模式使得原本由于接口不兼容而不能一起工作的類可以一起工作。

       在實際的生活中有很多例子,如:我們常使用的移動硬盤,無論是筆記本硬盤還是臺式機硬盤,對于數(shù)據(jù)的傳輸都不使用Usb的數(shù)據(jù)線,外接的硬盤盒就是將原來的硬盤數(shù)據(jù)傳輸方式適合Usb數(shù)據(jù)線。(哎,我那個硬盤盒買的時候還190元,其實一點都不值,整個一個盒,就那個轉(zhuǎn)接芯片比較值錢,我說50,人家不賣)。

       我再接著說適配器模式,先舉個簡單的代碼例子,我現(xiàn)在要做一個隊列的類,實現(xiàn)先進先出的功能。利用ArrayList對象。

       首先,我們先定義一些隊列的接口,接口中定義隊列的方法,代碼如下:

       interface IQueue

    {

        void push(object item);     //進隊列

        object putout();            //出隊列

        object ShowLastItem();      //返回隊列中最后一項

        object ShowFirstItem();     //返回隊列中第一項

    }

    下面我們再來利用ArrayList對象實現(xiàn)一個隊列:

    class Queue:IQueue

    {

        ArrayList adaptee;

       

        public Queue()

        {

            adaptee = new ArrayList();

        }

 

        public void push(object item)

        {

            adaptee.Add(item);

        }

 

        public object putout()

        {

            object item = adaptee[0];

            adaptee.RemoveAt(0);

            return item;

        }

 

        public object ShowLastItem()

        {

            return adaptee[adaptee.Count-1];

        }

 

        public object ShowFirstItem()

        {

            return adaptee[0];

        }

    }

    實現(xiàn)有了,現(xiàn)在用客戶端程序調(diào)用來看一下結(jié)果:

    class Class1

    {

        /// <summary>

        /// 應用程序的主入口點。

        /// </summary>

        [STAThread]

        static void Main(string[] args)

        {

            Queue queue = new Queue();

            queue.push(1);

            queue.push(2);

            queue.push(3);

            queue.push(4);

            queue.push(5);

            Console.Write("FirstItem:" + queue.ShowFirstItem().ToString() + "\n");

            Console.Write("LastItem:" + queue.ShowLastItem().ToString() + "\n");

            Console.Write("output:" + queue.putout().ToString() + "\n");

            queue.push(6);

            Console.Write("FirstItem:" + queue.ShowFirstItem().ToString() + "\n");

            Console.Write("LastItem:" + queue.ShowLastItem().ToString() + "\n");

            Console.Read();

        }

    }

    輸出結(jié)果:

    FirstItem:1

LastItem:5

output:1

FirstItem:2

LastItem:6

 

適配器模式實現(xiàn)有兩種類型:對象適配器、類適配器。上面的代碼是對象適配器方式。也就是適配器(Queue)中是使用被適配(ArrayList)的對象實現(xiàn)。它的結(jié)構(gòu)如下:


   
Gof
《設計模式》中提到了兩種Adapter適配器模式,一種叫對象適配器模式,另一種叫類適配器模式。對象適配器模式的結(jié)構(gòu)如上圖,也就是我剛才舉的那個例子,那什么是類適配器模式呢?實際上類適配器模式就是讓Adapter的實現(xiàn)繼承Adaptee。換句話說:類適配器模式是以繼承的方式來實現(xiàn),而對象適配器模式是以組合的方式實現(xiàn)。以前我們說過:繼承增加了模塊間的耦合程度,而組合降低了耦合程度,所以有人建議多使用對象適配器模式,少用類適配器模式。不過既然提到,我也具體談談類適配器模式。它的結(jié)構(gòu)如下圖:

    我們依然用上面的那個隊列的例子,首先我們要實現(xiàn)一個Adapter的類,這個類要繼承適配對象Adaptee類,也就是例子中的ArrayList,還有隊列接口,就是我們定義的IQueue,代碼如下:

    class ClassAdapter:ArrayList,IQueue

    {

        public ClassAdapter()

        {

           

        }

 

        public void push(object item)

        {

            this.Add(item);

        }

 

        public object putout()

        {

            object item = this[0];

            this.RemoveAt(0);

            return item;

        }

 

        public object ShowLastItem()

        {

            return this[this.Count-1];

        }

 

        public object ShowFirstItem()

        {

            return this[0];

        }

    }

    然后我們再修改一下客戶代碼:

        static void Main(string[] args)

        {

            ClassAdapter queue = new ClassAdapter();

            queue.push(1);

            queue.push(2);

            queue.push(3);

            queue.push(4);

            queue.push(5);

            Console.Write("FirstItem:" + queue.ShowFirstItem().ToString() + "\n");

            Console.Write("LastItem:" + queue.ShowLastItem().ToString() + "\n");

            Console.Write("output:" + queue.putout().ToString() + "\n");

            queue.push(6);

            Console.Write("FirstItem:" + queue.ShowFirstItem().ToString() + "\n");

            Console.Write("LastItem:" + queue.ShowLastItem().ToString() + "\n");

            Console.Read();

        }

    輸出結(jié)果為:

FirstItem:1

LastItem:5

output:1

FirstItem:2

LastItem:6

要說明一點:從實現(xiàn)的代碼看:ClassAdapter類同時繼承了ArrayList,IQueue,這樣違反了設計原則中的單一職責原則(SRP)——一個類應該僅有一個引起他變化的原因。

接下來,我們在看看Adapter模式的幾個要點:

1、              Adapter模式主要應用于“希望服用一些現(xiàn)存的類,但是接口又與復用環(huán)境要求不一致的情況”,在遺留代碼復用、類庫遷移等方面非常有用。

2、              Gof23定義了兩種Adapter模式的實現(xiàn)結(jié)構(gòu):對象適配器和類適配器。但類適配器采用“多繼承”的實現(xiàn)方式,帶來了不良的高耦合,所以一般不推薦使用。對象適配器采用“對象組合”的方式,更符合松耦合精神。

3、              Adapter模式本身要求我們盡可能的使用“面向接口的編程”風格,這樣才能在后期很方便的適配

Adapter模式的實現(xiàn)方法有很多,說到這我在舉一個例子,我現(xiàn)在有這樣一個場景。我有一輛BORA車子和BMWEngineWheel,我現(xiàn)在想改裝這輛BORA使其擁有BMWEngineWheel,我如何做呢?

首先,我們要擁有一些BMW的零部件,代碼如下:

class BMWPartClass

    {

        public void BMWEngine()

        {

            Console.Write("It is a BMWEngine\n");

        }

 

        public void BMWWheel()

        {

            Console.Write("It is a BMWWheel\n");

        }

}

然后,再來實現(xiàn)對這些零部件的適配,代碼如下:

interface ITarget

    {

        void Request();

    }

 

    class Adapter:ITarget

    {

        BMWPartClass adaptee = new BMWPartClass();

 

        public void Request()

        {

            adaptee.BMWEngine();

            adaptee.BMWWheel();

        }

}

對于我的BORA的實現(xiàn):

class MyBORAClass

    {

        public void Process(ITarget target)

        {

            target.Request();

        }

}

最后是客戶端代碼:

static void Main(string[] args)

        {

            MyBORAClass bora = new MyBORAClass();

            bora.Process(new Adapter());

            Console.Read();

    }

輸出結(jié)果是:

It is a BMWEngine

It is a BMWWheel

posted on 2006-05-29 16:53 KiddLee 閱讀(1456) 評論(5)  編輯 收藏 引用 網(wǎng)摘 所屬分類: 設計模式

FeedBack:
# 
@kid-li

UML圖有點問題,Target應該為接口:-)

另外補充一句:Adapter模式有一種亡羊補牢的味道。  回復  更多評論
  
# re: 設計模式學習筆記(七)——Adapter適配器模式 2006-05-29 17:33 kid_li
@TerryLee
哈哈,TerryLee,你的反應好快!佩服。
Target應該是接口,畫圖時這點的確沒注意,馬上改過來
  回復  更多評論
  
# re: 設計模式學習筆記(七)——Adapter適配器模式 2006-05-29 18:10 吳某人
我買的一個硬盤盒才20快。。

老兄的是什么硬盤盒。。那么貴。。  回復  更多評論
  
# re: 設計模式學習筆記(七)——Adapter適配器模式 2006-05-30 19:53 我本善良
我有一輛BORA車子和BMW的Engine和Wheel,我現(xiàn)在想改裝這輛BORA使其擁有BMW的Engine和Wheel,我如何做呢?
個人以為你舉這個例子說明適配器模式,有一點點不恰當。
如果這樣的場景關(guān)注于BORA車子可以使用BMW的Engine和Wheel。裝飾模式更適合一些。
如果是這樣的場景關(guān)注于BORA車子可以靈活的改變自己的Engine和Wheel策略模式更實話一些。
謝謝你文章可以給許多人點亮路燈,我這里是提一下我自己的意見。  回復  更多評論
  
# re: 設計模式學習筆記(七)——Adapter適配器模式 2006-05-31 08:56 kid_li
@我本善良
謝謝,的確有時刻意的去想例子,想的不是很準確。以后在舉例方面慎重一些。  回復  更多評論

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多