Franky's LIFE

          Anything... ...

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            53 隨筆 :: 87 文章 :: 6 評論 :: 0 Trackbacks
          ? Adapter 適配器模式是一種結構型模式,主要應對:由于應用環境的變化,常常需要將“一些現存的對象”放在新的環境中應用,但是,新環境要求的接口是現存對象所不滿足的。

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

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

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

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

          ?????? interface IQueue

          ??? {

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

          ??????? object putout();??????????? // 出隊列

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

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

          ??? }

          ??? 下面我們再來利用ArrayList對象實現一個隊列:

          ??? 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];

          ??????? }

          ??? }

          ??? 實現有了,現在用客戶端程序調用來看一下結果:

          ??? 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();

          ??????? }

          ??? }

          ??? 輸出結果:

          ??? FirstItem:1

          LastItem:5

          output:1

          FirstItem:2

          LastItem:6

          ?

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


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

          ??? 我們依然用上面的那個隊列的例子,首先我們要實現一個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();

          ??????? }

          ??? 輸出結果為:

          FirstItem:1

          LastItem:5

          output:1

          FirstItem:2

          LastItem:6

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

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

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

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

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

          Adapter 模式的實現方法有很多,說到這我在舉一個例子,我現在有這樣一個場景。我有一輛BORA車子和BMWEngineWheel,我現在想改裝這輛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");

          ??????? }

          }

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

          interface ITarget

          ??? {

          ??????? void Request();

          ??? }

          ?

          ??? class Adapter:ITarget

          ??? {

          ??????? BMWPartClass adaptee = new BMWPartClass();

          ?

          ??????? public void Request()

          ??????? {

          ??????????? adaptee.BMWEngine();

          ??????????? adaptee.BMWWheel();

          ??????? }

          }

          對于我的BORA的實現:

          class MyBORAClass

          ??? {

          ??????? public void Process(ITarget target)

          ??????? {

          ??????????? target.Request();

          ??????? }

          }

          最后是客戶端代碼:

          static void Main(string[] args)

          ??????? {

          ??????????? MyBORAClass bora = new MyBORAClass();

          ??????????? bora.Process(new Adapter());

          ??????????? Console.Read();

          ??? }

          輸出結果是:

          It is a BMWEngine

          It is a BMWWheel

          posted on 2007-03-19 20:50 Franky 閱讀(182) 評論(0)  編輯  收藏 所屬分類: IT知識
          主站蜘蛛池模板: 凤冈县| 临海市| 鄂托克旗| 富宁县| 罗定市| 霸州市| 天柱县| 留坝县| 唐山市| 南安市| 江达县| 崇文区| 奉化市| 全南县| 华容县| 武宁县| 吉林市| 屯门区| 阳高县| 易门县| 驻马店市| 枝江市| 大港区| 谢通门县| 巴中市| 那坡县| 堆龙德庆县| 西青区| 桂林市| 彩票| 大冶市| 托克逊县| 珠海市| 沙雅县| 商城县| 改则县| 舟曲县| 龙口市| 石城县| 桂阳县| 茌平县|