欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
從Adapter模式到Decorator模式
 

從Adapter模式到Decorator模式

作者/來(lái)源: Bruce Zhang

 

一、考察對象的Adapter模式

從上文看到,經(jīng)過(guò)引入Adapter模式,原有的結構得到了改進(jìn)。但我們還需要從客戶(hù)的角度分析程序,使結構更加地合理。(這里,我們僅限于考察對象的Adapter模式。類(lèi)的Adapter模式不存在下述問(wèn)題。這也印證了一個(gè)事實(shí),就是:對象的Adapter模式和類(lèi)的Adapter模式各有優(yōu)勢,也各有缺點(diǎn),設計時(shí)應根據實(shí)際情況考察。)

1、擴展的功能是否合理?

假設用戶(hù)希望調用VedioMedia同時(shí)具有Play()和Resize()功能。從前面的描述來(lái)看,客戶(hù)只需要實(shí)例化VedioAdapter類(lèi)對象,就可以調用了??磥?lái)結構是正確的。

2、類(lèi)型的擴展是否合理?

從目前的需求來(lái)看,要調用RM和MPEG類(lèi)型的對象,沒(méi)有任何問(wèn)題。但是正如呂震宇所說(shuō),在VedioMedia類(lèi)的Resize()方法中有一股腐化的味道。壞味道的根源就是if 條件語(yǔ)句。如果要增加新的視頻類(lèi)型,就需要修改Resize()方法了。這是一個(gè)設計的權衡。其實(shí)這個(gè)味道雖然夠壞,但好處是簡(jiǎn)單,也不用更多的對象;但耦合性比較差。

如果我們的目標是希望更好的架構以支持耦合的松散,目前的結構就需要微調了。調整后的類(lèi)圖如下: 

這樣需要改變VedioAdapter類(lèi)的代碼:

public

 

abstract

 

class VedioAdapter:IVedioScreen

{

 

protected vedioMedia _vedio;

 

 

public VedioAdapter(vedioMedia vedio)

 

{

  _vedio = vedio;

 }

 

public

 

void Play()

 

{

  _vedio.Play();  

 }

 

public

 

abstract

 

void Resize();

}

然后實(shí)現RMAdapter和MPEGAdatper:

public

 

class RMAdapter:VedioAdapter

{

 

public RMAdapter(VedioMedia vedio):base(vedio){}

 

 

public

 

override

 

void Resize()

 

{

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

 }

}

(MPEGAdapter的代碼省略)

這樣一改,要擴展就容易了,不過(guò)比之以前設計要復雜些,希望不會(huì )有人說(shuō)我過(guò)度設計。如果要考慮正確性的話(huà),RMAdapter的構造函數還需要考慮異常情況。由于構造函數的參數為VedioMedia類(lèi)型,因此,客戶(hù)在調用時(shí)可能會(huì )傳入MPEG類(lèi)型,此時(shí)RMAdapter類(lèi)型的Play()行為就會(huì )發(fā)生改變。這也是和Decorator最大的不同,就是我們必須限制對象的Play()方法不能做任何改變。

public RMAdapter(VedioMedia vedio):base(vedio)

{

 

if (!(vedio is RM))

  throw

 

new Exception(”VedioMedia object

 

is not correct!”);

}

3、是否與原有客戶(hù)系統兼容?

如果在原有的客戶(hù)系統中提供了如下的類(lèi)及方法:

public

 

class MediaFile

{

 

public

 

static

 

void Play(IMedia media)

 

{

  media.Play();

 }

}

那么客戶(hù)如下的調用是沒(méi)有任何問(wèn)題的:

MediaFile.Play(new RM());

然而,當客戶(hù)要使用新的Adapter對象呢?例如:

MediaFile.Play(new RMAdapter());

顯然是有問(wèn)題了,因為RMAdpater類(lèi)沒(méi)有實(shí)現IMedia接口,且RMAdpater類(lèi)的Play()方法和IMedia接口的Play()方法在性質(zhì)上也是有區別的。此時(shí),采用原有的設計就不正確了。改進(jìn)的方法很簡(jiǎn)單,就是讓VedioAdapter類(lèi)實(shí)現IMedia接口就可以了:

public abstract class VedioAdapter:IVedioScreen,IMedia

{

 ……

}

根據呂震宇所說(shuō),當VedioAdapter類(lèi)實(shí)現IMedia接口時(shí),言外之意就是該Adapter也適合AudioMedia類(lèi)型了。是否如此呢?可以說(shuō)是一半對,一半不對。對的原因,是由于A(yíng)udioMedia類(lèi)也實(shí)現了IMedia接口;但別忘了,我們適配的并非類(lèi),而是對象,也就是在VedioAdapter中傳遞進(jìn)來(lái)的VedioMedia對象。(如果我們將傳遞進(jìn)來(lái)的對象擴展為IMedia,那就糟糕了。震宇兄的結論就完全成立了。)同時(shí),我們在構造函數的異常處理,也保證了AudioMedia類(lèi)型對于VedioAdapter是非法的。

寫(xiě)到這里,我覺(jué)得本文已經(jīng)超出了原來(lái)的設想,有些研究的味道了。嗯,還算不錯。那么就繼續研究下去吧。

二、引入Decorator模式

按照最初的需求,我引入Decorator模式試一試。最初的需求是,需要為RM和MPEG類(lèi)在不改變原有代碼的情況下,添加Resize()方法,而其原來(lái)的Play()方法不變。調整設計類(lèi)圖:

上圖的橙紅色區域為Decorator模式的主體,至于IVedioScreen接口,僅僅是為VedioDecorator增加Resize()方法而引入的,其本身與Decorator無(wú)關(guān),除非我要實(shí)現的Decorator功能,通過(guò)該接口來(lái)實(shí)現。代碼如下:

public

 

abstract

 

class VedioDecorator:VedioMedia,IVedioScreen

{

 

private VedioMedia _vedio;

 

 

public VedioAdapter(vedioMedia vedio)

 

{

  _vedio = vedio;

 }

 

public VedioMedia Vedio

 

{

  get

 

{return _vedio;}

 }

 

public

 

abstract

 

void Resize();

}

注意看,與前面Adapter模式的VedioAdapter類(lèi)比較,除增加了對VedioMedia的派生外,還減少了Play(),因為該方法已經(jīng)從VedioMedia類(lèi)中派生獲得。這樣的話(huà),RMDecorator和MPEGDecorator,也需要做相應的改變:

public

 

class RMDecorator:VedioDecorator

{

 

public RMDecorator (VedioMedia vedio):base(vedio)

 

{

  if (!(vedio is RM))

   throw

 

new Exception(”VedioMedia object

 

is not correct!”);

 }

 

 

public

 

override

 

void Play()

 

{

  Vedio.Play();

 }

 

public

 

override

 

void Resize()

 

{

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

 }

}

到這個(gè)時(shí)候,我忽然覺(jué)得引入Decorator模式,已經(jīng)有些力不從心了。為什么呢?最大的障礙就是我們的需求不能更改VedioMedia類(lèi)型Play()方法的既有行為。這個(gè)時(shí)候,所謂的Decorator已經(jīng)失去了原來(lái)的意義。其實(shí)我覺(jué)得,此時(shí)的設計,應該是結合了Adapter模式與Decorator模式而衍生出的新的結構。

那么,我為什么還要在本文提出引入Decorator模式呢。這來(lái)源我對于設計模式一向的觀(guān)點(diǎn):不要為了模式而模式!GOF的23種模式,并非茴香豆的“茴”字,我也并非孔乙己,要你回答“茴”字的寫(xiě)法,卻忽略了使用設計模式的真正精神。設計模式歸根結底是拿來(lái)用的。只要符合你的要求,各種模式隨你怎么變都可以。因此,不管是前文所述的Adapter模式,還是改進(jìn)后的Adapter模式,或者引入的Decorator模式,其中的變化是靈活的,選擇權最終還是你。

三、正宗的Decorator模式

不過(guò),我還是很有興趣繼續探討下去,仍然借助媒體播放這個(gè)例子,來(lái)談一談Decorator模式的一般應用?,F在我們要求RM和MPEG媒體在播放前,首先要顯示媒體文件的版權信息。請注意,這個(gè)需求,并非是為RM等媒體增加ShowCopyright()方法,而Play()方法保持不變。恰恰相反,新的需求裝飾了Play()的行為,它要求Play()的同時(shí)能夠支持ShowCopyright的功能。類(lèi)圖如下:

在這里,VedioDecorator是裝飾類(lèi)的抽象類(lèi),而CopyRightVedioDecorator類(lèi)則具體裝飾了Play()的功能。

public

 

abstract

 

class VedioDecorator:VedioMedia

{

 

private VedioMedia _vedio;

 

 

public VedioAdapter(vedioMedia vedio)

 

{

  _vedio = vedio;

 }

 

public VedioMedia Vedio

 

{

  get

 

{return _vedio;}

 }

}

然后實(shí)現CopyRightVedioDecorator類(lèi),為Play()方法裝飾顯示版權信息的功能:

public

 

class CopyRightVedioDecorator:VedioDecorator

{

 

private CopyRight _copyRightMark;

 

 

public CopyRight CopyRightMark

 

{

  get

 

{return _copyRightMark;}

  set

 

{_copyRightMark = value;}

 }

 

public

 

override

 

void Play()

 

{

  _copyRightMark.ShowCopyRight();

  Vedio.Play();

 }

}

我們還可以繼續裝飾VedioMedia的Play行為,例如,要求在播放媒體文件之前,必須放一段廣告,那么我們可以繼續提供一個(gè)AdvertisementVedioDecorator裝飾類(lèi)。道理與上一樣,不再贅述。

通過(guò)本例,我們可以看到Decorator模式與對象的Adapter模式的區別。

實(shí)現的區別:

1、Decorator抽象類(lèi)應繼承要裝飾的類(lèi),同時(shí)又聚合該類(lèi)的實(shí)例對象;而對象的Adapter模式則只聚合,不繼承;

2、Decor模式并沒(méi)有引入新的接口,除非要裝飾的行為需要使用該接口;而對象的Adapter模式則引入了新的接口,以此來(lái)裝配原有的對象,使其具有了新接口的方法;

因此,適用的場(chǎng)景也就有所不同:

1、Decorator模式如其名,一般并不提供新的行為,而是在原有的行為上進(jìn)行補充,即裝飾的含義。

2、Adapter模式則是為對象引入新的行為,使其匹配新的接口,即為適配的意義所在。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
設計模式之Decorator(油漆工)
從Decorator,Adapter模式看Java/IO庫(一)
設計模式學(xué)習筆記(十五)——結構型模式總結
spring中的設計模式解析
設計模式中,屬于結構型模式的有哪些?
設計模式之創(chuàng )建型模式
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久