乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      從實例談Adapter模式

       ljjzlm 2006-08-04
       

      從實例談Adapter模式

      作者/來源: Bruce Zhang

       

      在系列一中, RM和MPEG類繼承了VideoMedia抽象類,而VideoMedia類又實現(xiàn)了IMedia接口,該接口僅僅提供了Play()方法。冰汽水的意思是希望為RM,MPEG提供與AudioMedia不同的屬性和方法。例如,對于視頻媒體而言,應(yīng)該有一個調(diào)整畫面大小的方法,如Resize()。而這個方法是IMedia接口所不具備的。

      那么怎樣為RM,MPEG類提供IMedia接口所不具備的Resize()方法呢?非常自然地,通過這個問題我們就引出Adapter模式的命題了。首先,要假設(shè)一個情況,就是原文的所有代碼,我們是無法改變的,這包括暴露的接口,類與接口的關(guān)系等等,都無法通過編碼的方式實現(xiàn)新的目標。只有這樣,引入Adapter模式才有意義。

      熟悉Adapter模式的人都知道,Adapter模式分為兩種:類的Adapter模式、對象的Adapter模式。下面我試圖根據(jù)本例對兩種方式進行說明及實現(xiàn)。在實現(xiàn)Adapter模式之前,有必要看看原來的類結(jié)構(gòu):

      左邊橙色的類為音頻媒體類型,右邊藍色的類為視頻媒體類型。所有的這些類型,包括類和接口都是無法改變的?,F(xiàn)在我們的目的就是要讓RM、MPEG具有Resize()方法。那么首先定義一個接口IVideoMedia,該接口具有Resize()方法。

      下面我們就根據(jù)Adapter模式來實現(xiàn)需求。

      一、類的Adapter模式

      既然要讓RM、MPEG具有Resize()方法,最好的辦法就是讓它們直接實現(xiàn)IVedioScreen接口。然而受到條件的限制,這兩個類類型是不可修改的。唯一可行的辦法就是為相應(yīng)的類新引入一個類類型,這就是Adapter模式中所謂的Adapter類了。它好比是一個轉(zhuǎn)接頭,通過它去實現(xiàn)IVedioScreen接口,同時又令其繼承原有的RM或MPEG類,以保留原有的行為。類圖如下:

      圖中的類RMAdapter和MPEGAdapter就是通過Adapter模式獲得的對象,它在保留了原有行為的同時,又擁有了IVedioScreen的功能。

      代碼如下:

      public

       

      interface IVedioScreen

      {

      void Resize();

      }

      public

       

      class RMAdapter:RM,IVedioScreen

      {

      public

       

      void Resize()

      {

      MessageBox.Show(”Change the RM screen’s size.”);

      }

      }

      public

       

      class MPEGAdapter:MPEG,IVedioScreen

      {

      public

       

      void Resize()

      {

      MessageBox.Show(”Change the MPEG screen’s size.”);

      }

      }

      也許很多人已經(jīng)注意到了,在使用這種方式建立Adapter時,存在一個局限,就是我們必須為每一個要包裹(Wrapping)的類,建立一個相應(yīng)的Adapter類。如上所述的RM對應(yīng)RMAdapter,MPEG對應(yīng)MPEGAdapter。必須如此,為什么呢?雖然RM和MPEG繼承了同一個抽象類VedioMedia,但其Play()方法,可能是不相同的。此時,相對應(yīng)的Adpater類只有直接繼承該具體類,方才可以保留其原來的Play()方法的行為本質(zhì)。

      OOP中很重要的思想是,盡量使用聚合而非繼承。讓我們換一種思路來考察Adapter模式。

      二、對象的Adapter模式

      對象的Adapter模式,與類的Adapter模式,最大的區(qū)別就是不采用繼承的方式,而是將要包裹的對象,以聚合的方式放到Adapter中,然后用委托的方式調(diào)用其對象的方法,實現(xiàn)類圖如下:

      比較兩種實現(xiàn)方式的類圖,可以得出兩個結(jié)論:

      1、對象的Adapter模式,減少了對象的個數(shù);

      2、耦合度更加松散;

      代碼如下:

      public

       

      interface IVedioScreen

      {

      void Resize();

      }

      public

       

      class VedioAdapter:IVedioScreen

      {

      private vedioMedia _vedio;

      public VedioAdapter(vedioMedia vedio)

      {

      _vedio = vedio;

      }

      public

       

      void Play()

      {

      _vedio.Play();

      }

      public

       

      void Resize()

      {

      if (_vedio is RM)

      MessageBox.Show(”Change the RM screen’s size.”);

      else

      MessageBox.Show(”Change the MPEG screen’s size.”);

      }

      }

      以這種方式形成的VedioAdapter,由于沒有和RM、MPEG直接發(fā)生關(guān)系,并通過在構(gòu)造函數(shù)傳遞參數(shù)的方式,等待客戶端使用Adapter時,才將具體的VedioMedia對象傳遞給Adapter,顯得耦合度更加松散,更加靈活。

      我們來看客戶端調(diào)用時,兩者的區(qū)別:

      1、類的Adapter模式

      public

       

      class Client

      {

      public

       

      static

       

      void Main()

      {

      RMAdapter rmAdapter =

       

      new RMAdapter();

      MPEGAdapter mpegAdapter =

       

      new MPEGAdapter();

      rmAdapter.Play();

      rmAdapter.Resize();

      mpegAdapter.Play();

      mpegAdapter.Resize();

      }

      }

      2、對象的Adapter模式

      public

       

      class Client

      {

      public

       

      static

       

      void Main()

      {

      VedioAdapter rmAdapter =

       

      new VedioAdapter(new RM());

      VedioAdapter mpegAdapter =

       

      new VedioAdapter(new MPEG());

      rmAdapter.Play();

      rmAdapter.Resize();

      mpegAdapter.Play();

      mpegAdapter.Resize();

      }

      }

      其實,對于對象的Adapter模式,還可以做一些改進,就是用屬性或方法來取代構(gòu)造函數(shù)傳遞被包裹對象的方式。代碼修改如下:

      public

       

      class VedioAdapter:IVedioScreen

      {

      private vedioMedia _vedio;

      public VedioMedia Vedio

      {

      set

       

      {_vedio = value;}

      }

      ……

      }

      這樣,上面的客戶端調(diào)用就更簡單了:

      public

       

      class Client

      {

      public

       

      static

       

      void Main()

      {

      VedioAdapter adapter =

       

      new VedioAdapter();

      adapter.Vedio =

       

      new RM();

      adapter.Play();

      adapter.Resize();

      adapter.Vedio =

       

      new MPEG();

      adapter.Play();

      adapter.Resize();

      }

      }

      通過運用Adapter模式,擴展了新的接口,而原有的類型并不需要做任何改變,這就是Adapter模式的實質(zhì),也是為什么取名為Adapter的原因之所在了。同時,我們要注意的是,在運用Adapter模式時,必須審時度勢,根據(jù)具體的情況,抉擇最優(yōu)的方式,或者采用類的Adapter模式,或者采用對象的Adapter模式。決定權(quán)在與你,菜單給你送上來了,看看自己的腰包,想想點什么樣的菜吧。

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

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多