designPattern

Design Pattern(15) - Proxy

代理模式是個很常用的設計模式 當無法直接訪問某個對象或是其他理由導致訪問這個對象很困難的時候 就可以用一個代理對象來做間接的訪問 很困難的理由包含物件在遠端 或是建立成本高 或是需要安全控管等等

這篇注重在介紹各種使用Proxy的時機 比較像是大方向 不會有實作細節

藤原佐為

我的好朋友藤原佐為是平安時代的天才棋士 因為某次在天皇面前下棋時被誣陷作弊而含冤自盡 因為尚未確認自己是否已達神乎其技 所以遲遲不投胎 在世上徘徊了千年之久 Alt text

雖然他能思考 棋力也近乎神級 但他卻沒有辦法靠自己跟別人下棋 所以需要找一個人幫他忙 這個人就是進藤光 Alt text

所以對於想跟佐為挑戰下棋的人 他們只要跟進藤光下就好了 挑戰者不需要管近藤光怎麼跟佐為溝通等等的細節 只要把進藤光當成是佐為就可以 因為他們兩對外的接口一樣

恭喜你已經瞭解了proxy pattern 現在我們來看看定義

代理模式

讓某個物件有個替身 並由這個替身控制對於原對象的使用 藉以控制外界對此物件的控制

代理模式結構

Alt text

代理模式種類

1.遠端代理人: 為一個遠端的物件提供一個在本地的替身 遠端可以是不同台電腦 或是不同個JVM

2.虛擬代理人: 如果需要創建的物件需要花費很多資源 可以先創一個花費少資源的先頂一下 真實對象只有在需要的時候才創建 一個常見的做法是Copy-on-write

3.保護代理人: 控制對一個對象的訪問 可以給不同用戶不同的使用權限

4.緩衝(Cache)代理人: 替某一個複雜操作或運算的結果提供一個暫存的空間 只有第一次計算會聯絡RealSubject 之後一陣子就用這個cache

5.智能(Smart)代理人: 當RealSubject被call時增加一些額外的功能 比如說被call了幾次等等 或是log使用情況

事實上第五個種類挺廣義的 你可以想成在真正call RealSubject.Request之前跟之後 可以先call Proxy.preRequest跟Proxy.postRequest 算是替RealSubject增加額外的功能

6.防火牆代理人: 控制網路資源的存取 保護內部免於受到外面的侵害

7.同步化代理人: 提供安全的存取 讓多個thread存取同一個物件時不會出錯

8.複雜度隱藏代理人: Facade Proxy

優缺點

1.Proxy協調了Client跟RealSubject 降低了兩者的依賴 降低系統的耦合

2.當然多了一層 可能會讓request變慢

問答時間

Q1: 我有Proxy很好 那我要怎麼保證Client call我的proxy而不是去call RealSubject呢

A1: 提供一個工廠 用這個工廠來傳出一個物件 這個物件可能是RealSubject可能是Proxy 事實上Client也不在乎他是誰 Client就是跟他溝通就對了

Q2: 我好像覺得Proxy跟Adaptor有點像…?

A2: Adaptor是改變物件的介面讓他跟其他物件一致 Proxy是實作相同的介面

Q3: 我好像覺得Proxy跟Decorator有點像…?

A3: Proxy是控制物件的存取 代表了真實的物件 Decorator是動態增加了物件功能或行為




「千年雖過,黑白二色依然讓我迷醉! 千年雖逝,棋子拍落的金石之音仍是震撼我心! 千年滄桑,世事變遷,不變的是棋盤上驚心動魄的撕殺,棋士內心的執著,還有……對圍棋恆古不滅的熱情!千年放浪,閱盡沉浮人生,不變的是我,醉心於棋盤上的千變萬化,依戀於相知相伴的幸福,以及對神之一手永無停息的追逐!                                                                                           藤原佐為