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






























如果說這個計算程序部署在我們本地計算機上,使用就非常之簡單了,我們也就不用去考慮
圖
3
這時候調(diào)用
Math
類的方法就沒有下面那么簡單了,因為我們更多的還要去考慮網(wǎng)絡(luò)的問題,對接收到的結(jié)果解包等一系列操作。
Proxy
模式,我們使用一個本地的代理來替
Math
類打點一切,即為我們的系統(tǒng)引入了一層間接層,示意圖如下

























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


































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


































此時我們在客戶程序中就可以像使用Math類一樣來使用MathProxy類了:























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

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