這是本人的設計模式學習筆記,把本身學習過程當中的一些總結和認識記錄下來,與諸君共勉。本日爲你們帶來代理模式。ajax
代理的任務是對本體的訪問進行控制,並暴露出與本體徹底相同的接口,將全部對它進行的方法調用傳遞給本體。注意代理既不像裝飾者同樣添加行爲,也不像外觀模式同樣簡化接口,記住:proxy‘s interface = origin’s interface。下面咱們給出代理模式的結構示意圖。設計模式
遠程代理用於訪問位於另外一個環境中的對象,另外一種環境的意義有着普遍的語義,例如在Java中意味着另外一個JVM中得對象。實現遠程代理須要有客戶端助手也就是代理對象來接受客戶的請求並傳達給服務端,也要有服務端助手來解析請求。遠程對象通常長期存在,下面也給出示意圖。遠程代理也能夠被用來訪問其餘語言中的對象。緩存
最後,介紹一些術語:安全
虛擬代理用於控制對那種建立開銷很大的本體的訪問,將本體的實例化推遲到有方法被調用的時候,有時還會提供關於實例化狀態的反饋。下面給出一張示意圖:服務器
jsproxy.prototype._init=function(){ if(this.entity===null){ this.entity= new Entity(this.data); } };
保護代理一般根據客戶身份控制對特定方法的訪問。多線程
這裏咱們列出一些在上面沒有提到的代理:app
先舉一個例子,ajax機制中,你想拉取遠程資源並進行一些操做,你能夠在本地建立代理對象來暴露這些操做接口,而後就像操做本地對象同樣完成操做,實際的xhr對象和遠程請求等均可以隱藏在代理內部,具體能夠參考jQuery的ajax服務。固然每每這種例子不會那麼純粹,它們或多或少帶有裝飾器、外觀模式的種種特色,但它們確實實現了代理的目的,不是嗎?異步
再好比搜索框,它們要查詢服務器並拉取數據,但你並不是每次訪問該頁面都使用搜索框啊,使用虛擬代理就能夠在用戶真的搜索時再請求,固然你會說直接用事件不就得了。可是異步加載的次數和類別夠複雜,你可能會但願僅僅對view暴露接口。虛擬代理總會派上用場。函數
以虛擬代理爲例學習
jsvar Proxy=function(){ this.args=arguments; this.initialized=false; this.subject={};//構建的本體 this.class={...};//本體的構造函數 ... var self=this; for(var key in this.class.prototype){ if(typeof this.class.prototype[key] !== "function") continue; (function(methodName){ self[methodName]=function(){ if(!self.initialized) return; return self.subject[methodName].apply(self.subject,arguments); }; })(key); } }; Proxy.prototype._init=function(){...}; Proxy.prototype._checkInitialization=function(){...};//阻止在初始化以前方法被調用 Proxy.prototype._isInitialized=function(){...};