本文的例子和部分內(nèi)容均來自www.jdon.com的《GoF 23種設(shè)計模式》系列文章
一、Proxy模式的適用場合
1.授權(quán)機制
不同級別的用戶對同一對象擁有不同的訪問權(quán)利,如Jive論壇系統(tǒng)中,就使用Proxy進行授權(quán)機制控制,訪問論壇有兩種人:注冊用戶和游客(未注冊用戶),Jive中就通過類似ForumProxy這樣的代理來控制這兩種用戶對論壇的訪問權(quán)限.
2.某個客戶端不能直接操作到某個對象,但又必須和那個對象有所互動.
舉例兩個具體情況:
(1)如果那個對象是一個是很大的圖片,需要花費很長時間才能顯示出來,那么當這個圖片包含在文檔中時,使用編輯器或瀏覽器打開這個文檔,打開文檔必須很迅速,不能等待大圖片處理完成,這時需要做個圖片Proxy來代替真正的圖片.
(2)如果那個對象在Internet的某個遠端服務(wù)器上,直接操作這個對象因為網(wǎng)絡(luò)速度原因可能比較慢,那我們可以先用Proxy來代替那個對象.
--摘自Jdon的《GoF 23種設(shè)計模式》
二、使用Proxy模式實現(xiàn)的授權(quán)機制
個人觀點一
從isSystemOrForumAdmin()方法體中我們可以看到權(quán)限設(shè)計的一種方法:
·定義一個表示權(quán)限的類,在這個類中定義所有的權(quán)限條目(例如這里的FORUM_ADMIN),以數(shù)字表示
·在這個類中定義一個數(shù)組,用于表示一個用戶所具有的所有權(quán)限的集合,數(shù)組的長度就是所有權(quán)限的數(shù)目總和
·使用諸如values[FORM_ADMIN]來獲取用戶是否具有某一項權(quán)限
三、對Jive論壇中Proxy模式使用的理解
計模式/proxy_code2.jpg)
計模式/proxy_code3.jpg)
個人觀點二
Request --(1)--> ForumProxy --(2)--> ForumPermissions
| |
| <-----------(3)------- | (權(quán)限驗證通過)
| |
(訪問)| ----------- (4)------> | Form
從上面的代碼段和這個流程圖中我們可以看到Proxy模式實現(xiàn)權(quán)限驗證的過程:
·請求都必須先經(jīng)過Proxy
·Proxy類中包含了一個Permission類,用于獲取當前用戶所具有的權(quán)限
·Proxy類根據(jù)用戶的權(quán)限將請求轉(zhuǎn)發(fā)給真正的后臺對象或拒絕請求
Proxy類具有幾個特點
·Proxy類一般都實現(xiàn)或繼承了后臺對象接口或抽象類,在其中實現(xiàn)了后臺對象接口的方法,這樣外界和代理類打交道的客戶端看到的是和后臺對象一樣的接口。根本不知道自在和代理對象打交道。
·Proxy類一般都含有一個后臺對象作為其成員,因為代理類需要在其實現(xiàn)接口的方法中調(diào)用后臺對象的真正方法來實現(xiàn)業(yè)務(wù)邏輯。
·Proxy類一般都需要包含一個能夠驗證用戶請求是否合法的對象,如上例中的ForumPermisssions類,作為轉(zhuǎn)發(fā)或拒絕用戶請求的判斷依據(jù)
四、Jive論壇中Proxy模式與Factory模式的結(jié)合
計模式/proxy_code4.jpg)
個人觀點三
Proxy結(jié)合Factory模式的實現(xiàn)流程
Request --(1)-- > ForumFactoryProxy --(2)-- > FourmPermissions
| |
| <----------- (3) ------------- | (驗證通過)
| |
| ------------- (4) -----------> | ForumFactory
| |
Forum | <------------ (5) ------------ | (創(chuàng)建)
| |
(封裝) | ------------- (6) -----------> | ForumProxy
可以看到這里有2個Proxy對象,一個是工廠的Proxy,一個是產(chǎn)品的Proxy,前者決定用戶是否有權(quán)創(chuàng)建一個Forum,后者決定用戶是否有權(quán)使用Forum。
但工廠創(chuàng)建出一個Form對象后,就將這個Forum對象和其它的對象傳給ForumProxy對象,以后所有對Forum的訪問和操作都由ForumProxy來代理。(參見個人觀點二)
所以我們看到:假如我們不想讓用戶直接訪問后臺對象或需要設(shè)置不同的訪問、操作權(quán)限,我們就可以使用Proxy模式
-------------------------------------------------------------
生活就像打牌,不是要抓一手好牌,而是要盡力打好一手爛牌。