Proxy Pattern
讓某個物件有個替身,藉以控制外界對物件的接觸。就是個經紀人的概念。(欸)
Proxy pattern 主要目的在於「控制存取」,被代理的物件可以是遠端主機上的物件、建立成本高(例如需要時間下載)的物件、或者需要做存取權限管控的物件。
UML
很簡單的 UML,client 透過 interface Subject 使用物件,所以它不用知道使用的是真正有功能的物件 RealSubject 還是只是代理人 Proxy。Proxy 依據型態不同會用不同方式取得 RealSubject、使用 RealSubject 的功能,再將結果丟回給 client。
除了操作 interface 外,要讓 client 使用 proxy 而非真正的 object,有個方法是用 factory 產生物件、傳回給 client,不然 client 自己 new 了個 XXXProxy,看也知道不是真正的 object 啊 XD。不過,是不是真有必要再加一層 factory 隱藏使用 proxy 的事實倒是依情況而定,簡單的情境下讓 client 自己去生 XXXProxy 也不會怎麼樣,不見得非得用 factory 增加複雜度。
Proxy 與它的變種們
Remote Proxy
代理另一台電腦上的物件或 service 等等的代理人。使用 proxy 的 client 基本上不會知道 proxy 多做了網路連線、傳遞資料等等的事情,例如 Java 的 RMI(Remote Method Invocation)(這東西應該有點年代了,就當作是個簡單的例子就好)。
Virtual Proxy
代理建立成本很高的 object,所謂成本很高可能是需要比較多時間等等,例如 video object 需要從網路抓影片、回應很慢的 API 等等。等待過程中但又不希望卡到 UI 操作,這時候就可以透過 virtual proxy 先回一個 loading 畫面,等到 video 抓好或 API 回來之後,就由真正的 object 做事。
Protection Proxy
顧名思義,保護真正 object 的 proxy,它會根據權限決定外部可不可以存取真正的 object。
Dynamic Proxy
Java 把事情搞得更複雜,弄了個 dynamic proxy 出來,在 package java.lang.reflect
。
簡單來說,Java 讓 programmer 連 proxy 都不用寫了,只要寫個 InvocationHandler
讓 proxy object call,runtime 才依據要代理的 object 生出 proxy object。除了讓人更懶之外不太懂為什麼要搞這個出來…
其他奇奇怪怪的 Proxy 們
放關鍵字,需要用再查。
Firewall proxy、Caching proxy、Synchronization proxy、Smart Reference proxy、Complexity Hiding proxy、Copy-On-Wrtie proxy。
網路上常說的 proxy server,就有 cache 跟控制網頁存取的功能。
Proxy 與其他 pattern 的不同
Decorator
proxy 跟 decorator 都是對一個物件包裝,有點像,但是兩者的意圖不同。proxy 的目的是控制存取,decorator 則是增加功能。而且 proxy 通常不會一直包一直包、像洋蔥一樣好多層,decorator 會依據想要的功能一直包。
Adapter
proxy 看到一半,我就想,啊這跟 adapter 不是一樣嗎!不都是在使用的 client 跟真正的 objec 之間加一層!!!(施主冷靜)
還是不一樣啦。adapter 會改變 interface,例如 function 參數不一樣,proxy 會 implement 同樣的 interface。