小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

從實(shí)例談Adapter模式

 ljjzlm 2006-08-04
 

從實(shí)例談Adapter模式

作者/來源: Bruce Zhang

 

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

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

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

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

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

一、類的Adapter模式

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

圖中的類RMAdapter和MPEGAdapter就是通過Adapter模式獲得的對象,它在保留了原有行為的同時(shí),又擁有了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時(shí),存在一個(gè)局限,就是我們必須為每一個(gè)要包裹(Wrapping)的類,建立一個(gè)相應(yīng)的Adapter類。如上所述的RM對應(yīng)RMAdapter,MPEG對應(yīng)MPEGAdapter。必須如此,為什么呢?雖然RM和MPEG繼承了同一個(gè)抽象類VedioMedia,但其Play()方法,可能是不相同的。此時(shí),相對應(yīng)的Adpater類只有直接繼承該具體類,方才可以保留其原來的Play()方法的行為本質(zhì)。

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

二、對象的Adapter模式

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

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

1、對象的Adapter模式,減少了對象的個(gè)數(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時(shí),才將具體的VedioMedia對象傳遞給Adapter,顯得耦合度更加松散,更加靈活。

我們來看客戶端調(diào)用時(shí),兩者的區(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();

}

}

其實(shí),對于對象的Adapter模式,還可以做一些改進(jìn),就是用屬性或方法來取代構(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();

}

}

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

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

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多