——.NET設(shè)計(jì)模式系列之十四
Terrylee
,2006年5月
摘要:在軟件系統(tǒng)中,有些對(duì)象有時(shí)候由于跨越網(wǎng)絡(luò)或者其他的障礙,而不能夠或者不想直接訪問(wèn)另一個(gè)對(duì)象,如果直接訪問(wèn)會(huì)給系統(tǒng)帶來(lái)不必要的復(fù)雜性,這時(shí)候可以在客戶程序和目標(biāo)對(duì)象之間增加一層中間層,讓代理對(duì)象來(lái)代替目標(biāo)對(duì)象打點(diǎn)一切。這就是本文要說(shuō)的
Proxy
模式。
主要內(nèi)容
1
.例說(shuō)
Proxy
模式
2
.
Proxy
模式效果及實(shí)現(xiàn)要點(diǎn)
……
概述
在軟件系統(tǒng)中,有些對(duì)象有時(shí)候由于跨越網(wǎng)絡(luò)或者其他的障礙,而不能夠或者不想直接訪問(wèn)另一個(gè)對(duì)象,如果直接訪問(wèn)會(huì)給系統(tǒng)帶來(lái)不必要的復(fù)雜性,這時(shí)候可以在客戶程序和目標(biāo)對(duì)象之間增加一層中間層,讓代理對(duì)象來(lái)代替目標(biāo)對(duì)象打點(diǎn)一切。這就是本文要說(shuō)的
Proxy
模式。
意圖
為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問(wèn)。
結(jié)構(gòu)圖
圖1 Proxy模式結(jié)構(gòu)圖
生活中的例子
代理模式提供一個(gè)中介以控制對(duì)這個(gè)對(duì)象的訪問(wèn)。一張支票或銀行存單是賬戶中資金的代理。支票在市場(chǎng)交易中用來(lái)代替現(xiàn)金,并提供對(duì)簽發(fā)人賬號(hào)上資金的控制。
圖2使用銀行存單例子的Proxy模式對(duì)象圖
Proxy
模式解說(shuō)
在軟件系統(tǒng)中,我們無(wú)時(shí)不在跨越障礙,當(dāng)我們?cè)L問(wèn)網(wǎng)絡(luò)上一臺(tái)計(jì)算機(jī)的資源時(shí),我們正在跨越網(wǎng)絡(luò)障礙,當(dāng)我們?nèi)ピL問(wèn)服務(wù)器上數(shù)據(jù)庫(kù)時(shí),我們又在跨越數(shù)據(jù)庫(kù)訪問(wèn)障礙,同時(shí)還有網(wǎng)絡(luò)障礙。跨越這些障礙有時(shí)候是非常復(fù)雜的,如果我們更多的去關(guān)注處理這些障礙問(wèn)題,可能就會(huì)忽視了本來(lái)應(yīng)該關(guān)注的業(yè)務(wù)邏輯問(wèn)題,
Proxy
模式有助于我們?nèi)ソ鉀Q這些問(wèn)題。我們以一個(gè)簡(jiǎn)單的數(shù)學(xué)計(jì)算程序?yàn)槔@個(gè)程序只負(fù)責(zé)進(jìn)行簡(jiǎn)單的加減乘除運(yùn)算:
Proxy
模式了。但現(xiàn)在問(wèn)題是這個(gè)
Math
類并沒(méi)有部署在我們本地,而是部署在一臺(tái)服務(wù)器上,也就是說(shuō)
Math
類根本和我們的客戶程序不在同一個(gè)地址空間之內(nèi),我們現(xiàn)在要面對(duì)的是跨越
Internet
這樣一個(gè)網(wǎng)絡(luò)障礙:






























如果說(shuō)這個(gè)計(jì)算程序部署在我們本地計(jì)算機(jī)上,使用就非常之簡(jiǎn)單了,我們也就不用去考慮
圖
3
這時(shí)候調(diào)用
Math
類的方法就沒(méi)有下面那么簡(jiǎn)單了,因?yàn)槲覀兏嗟倪€要去考慮網(wǎng)絡(luò)的問(wèn)題,對(duì)接收到的結(jié)果解包等一系列操作。
Proxy
模式,我們使用一個(gè)本地的代理來(lái)替
Math
類打點(diǎn)一切,即為我們的系統(tǒng)引入了一層間接層,示意圖如下

























為了解決由于網(wǎng)絡(luò)等障礙引起復(fù)雜性,就引出了
圖
4
我們?cè)?
MathProxy
中對(duì)實(shí)現(xiàn)
Math
數(shù)據(jù)類的訪問(wèn),讓
MathProxy
來(lái)代替網(wǎng)絡(luò)上的
Math
類,這樣我們看到
MathProxy
就好像是本地
Math
類,它與客戶程序處在了同一地址空間內(nèi):
Math
類的代理,存在的一個(gè)問(wèn)題是我們?cè)?
MathProxy
類中調(diào)用了原實(shí)現(xiàn)類
Math
的方法,但是
Math
并不一定實(shí)現(xiàn)了所有的方法,為了強(qiáng)迫
Math
類實(shí)現(xiàn)所有的方法,另一方面,為了我們更加透明的去操作對(duì)象,我們?cè)?
Math
類和
MathProxy
類的基礎(chǔ)上加上一層抽象,即它們都實(shí)現(xiàn)與
IMath
接口,示意圖如下:


































現(xiàn)在可以說(shuō)我們已經(jīng)實(shí)現(xiàn)了對(duì)
示意性代碼如下:


































此時(shí)我們?cè)诳蛻舫绦蛑芯涂梢韵袷褂肕ath類一樣來(lái)使用MathProxy類了:























到這兒整個(gè)使用Proxy模式的過(guò)程就完成了,回顧前面我們的解決方案,無(wú)非是在客戶程序和Math類之間加了一個(gè)間接層,這也是我們比較常見(jiàn)的解決問(wèn)題的手段之一。另外,對(duì)于程序中的接口Imath,并不是必須的,大多數(shù)情況下,我們?yōu)榱吮3謱?duì)對(duì)象操作的透明性,并強(qiáng)制實(shí)現(xiàn)類實(shí)現(xiàn)代理類所要調(diào)用的所有的方法,我們會(huì)讓它們實(shí)現(xiàn)與同一個(gè)接口。但是我們說(shuō)代理類它其實(shí)只是在一定程度上代表了原來(lái)的實(shí)現(xiàn)類,所以它們有時(shí)候也可以不實(shí)現(xiàn)于同一個(gè)接口。
效果及實(shí)現(xiàn)要點(diǎn)
Proxy
模式根據(jù)種類不同,效果也不盡相同:
1
.遠(yuǎn)程(
Remote
)代理:為一個(gè)位于不同的地址空間的對(duì)象提供一個(gè)局域代表對(duì)象。這個(gè)不同的地址空間可以是在本機(jī)器中,也可是在另一臺(tái)機(jī)器中。遠(yuǎn)程代理又叫做大使(
Ambassador
)。好處是系統(tǒng)可以將網(wǎng)絡(luò)的細(xì)節(jié)隱藏起來(lái),使得客戶端不必考慮網(wǎng)絡(luò)的存在。客戶完全可以認(rèn)為被代理的對(duì)象是局域的而不是遠(yuǎn)程的,而代理對(duì)象承擔(dān)了大部份的網(wǎng)絡(luò)通訊工作。由于客戶可能沒(méi)有意識(shí)到會(huì)啟動(dòng)一個(gè)耗費(fèi)時(shí)間的遠(yuǎn)程調(diào)用,因此客戶沒(méi)有必要的思想準(zhǔn)備。
2
.虛擬(
Virtual
)代理:根據(jù)需要?jiǎng)?chuàng)建一個(gè)資源消耗較大的對(duì)象,使得此對(duì)象只在需要時(shí)才會(huì)被真正創(chuàng)建。使用虛擬代理模式的好處就是代理對(duì)象可以在必要的時(shí)候才將被代理的對(duì)象加載;代理可以對(duì)加載的過(guò)程加以必要的優(yōu)化。當(dāng)一個(gè)模塊的加載十分耗費(fèi)資源的情況下,虛擬代理的好處就非常明顯。
3
.
Copy-on-Write
代理:虛擬代理的一種。把復(fù)制(克隆)拖延到只有在客戶端需要時(shí),才真正采取行動(dòng)。
4
.保護(hù)(
Protect or Access
)代理:控制對(duì)一個(gè)對(duì)象的訪問(wèn),如果需要,可以給不同的用戶提供不同級(jí)別的使用權(quán)限。保護(hù)代理的好處是它可以在運(yùn)行時(shí)間對(duì)用戶的有關(guān)權(quán)限進(jìn)行檢查,然后在核實(shí)后決定將調(diào)用傳遞給被代理的對(duì)象。
5
.
Cache
代理:為某一個(gè)目標(biāo)操作的結(jié)果提供臨時(shí)的存儲(chǔ)空間,以便多個(gè)客戶端可以共享這些結(jié)果。
6
.防火墻(
Firewall
)代理:保護(hù)目標(biāo),不讓惡意用戶接近。
7
.同步化(
Synchronization
)代理:使幾個(gè)用戶能夠同時(shí)使用一個(gè)對(duì)象而沒(méi)有沖突。
8
.智能引用(
Smart Reference
)代理:當(dāng)一個(gè)對(duì)象被引用時(shí),提供一些額外的操作,比如將對(duì)此對(duì)象調(diào)用的次數(shù)記錄下來(lái)等。
總結(jié)
在軟件系統(tǒng)中,增加一個(gè)中間層是我們解決問(wèn)題的常見(jiàn)手法,這方面
Proxy
模式給了我們很好的實(shí)現(xiàn)。
參考資料
Erich Gamma
等,《設(shè)計(jì)模式:可復(fù)用面向?qū)ο筌浖幕A(chǔ)》,機(jī)械工業(yè)出版社
Robert C.Martin
,《敏捷軟件開發(fā):原則、模式與實(shí)踐》,清華大學(xué)出版社
閻宏,《
Java
與模式》,電子工業(yè)出版社
Alan Shalloway James R. Trott
,《
Design Patterns Explained
》,中國(guó)電力出版社
MSDN WebCast
《
C#
面向?qū)ο笤O(shè)計(jì)模式縱橫談
(13)
:
Proxy
代理模式
(
結(jié)構(gòu)型模式
)
》
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
