javascript
javascript设计模式-代理模式
代理的結構
代理模式的最基本形式就是對訪問進行控制。代理對象和另一個對象實現的是同樣的接口。代理對象只是節制對本體的訪問。
代理對象不會在另一個對象上添加或修改方法,也不會簡化對象的接口,所有對方法的調用都會被傳遞給本體。
虛擬代理
用于控制對那種創建開銷很大的本體的訪問。他會把本體的實例化推遲到有方法被調用的時候。
代理對象具有與本體類實例對象的相同的方法,想操作本體類實例對象必須先通過代理對象,從而實現對本體類實例對象的控制。
創建虛擬代理的通用模式
示例:圖片預加載
let myImage = (function (src) {let node = document.createElement('img');document.body.appendChild(node);return {setSrc(src){node.src = src;}} })();let proxyImg = (function (){let img = new Image();img.onload = function (){myImage.setSrc(this.src);}return {setSrc(src){myImage.setSrc('');img.src=src;}} })();示例:合并http請求
當有多個多選框,用戶點擊多選框進行上傳文件時,當用戶點擊的過快,會導致服務器壓力過大,此時需要通過虛擬代理,減少在某一時刻發送的請求數量。
let syncrequest = function (ids) {console.log('開始同步文件', ids); }let proxSync = (function () {let cache = [],timer;return function (id) {cache.push(id);if (timer) {return;}timer = setTimeout(() => {syncrequest(cache.join(','));clearTimeout(timer);timer = null;}, 2000);} })();let checkbox = document.getElementsByTagName('input'); for(let i = 0, c; c = checkbox[i++];){c.onclick = function(){if(this.checked === true){proxSync(this.id);}} }遠程代理
遠程代理用于訪問另一個環境中的對象。
這種方式很難照搬到JavaScript中:
控制對其他語言中的本體的訪問。這種本體可能是Web服務資源,也可能是PHP對象,很難說你所使用的是什么模式。
安全代理
安全代理:用來控制真實對象的訪問權限,即滿足條件的可以訪問,不滿足條件的不能訪問
class Order {constructor(productName, productCount, orderUserName) {this.productName = productName;this.productCount = productCount;this.orderUser = orderUserName;}// 獲取訂單中產品的名稱getProductName() {return this.productName;}// 設置訂單中產品的名稱setProductName(productName) {this.productName = productName;}// 獲取訂單的用戶getOrderUserName() {return this.orderUserName;}// 設置訂單的用戶setOrderUserName(orderUserName) {this.orderUserName = orderUserName;}// 獲取產品數量getProductCount() {return this.oproductCount;}// 設置產品數量setProductCount(productCount) {this.productCount = productCount;}}class ProxyObject {constructor(realObject) {this.realObject = realObject;}// 獲取訂單中產品的名稱getProductName() {if (userName === this.realObject.orderUserName) {return this.realObject.productName;}}// 設置訂單中產品的名稱setProductName(productName, userName) {if (userName === this.realObject.orderUserName) {this.realObject.productName = productName;}}// 獲取訂單的用戶getOrderUserName() {if (userName === this.realObject.orderUserName) {return this.realObject.orderUserName;}}// 設置訂單的用戶setOrderUserName(orderUserName, userName) {if (userName === this.realObject.orderUserName) {this.realObject.orderUserName = orderUserName;}}// 獲取產品數量getProductCount() {return this.realObject.productCount;}// 設置產品數量setProductCount(productCount, userName) {if (userName === this.realObject.orderUserName) {this.realObject.productCount = productCount;}}}let order = new Order('西瓜', 1, 'wang');let subject = new ProxyObject(order);let productCount = subject.getProductCount(order.orderUserName);console.log(productCount);緩存代理
緩存代理可以為一些開銷大的運算結果提供暫時的存儲,在下次運算時,如果傳遞進來的參數跟之前一致,則可以直接返回前面存儲的運算結果
以計算乘積的程序為例,mult()方法用于計算乘積并返回計算后的結果,proxyMult用于把mult()計算后的結果緩存,當有相同的參數時,把參數對應的結果返回,如果沒有相同的參數,把參數的乘積計算后緩存然后返回結果。
var mult = function () {console.log('開始計算乘積');var a = 1;for (var i = 0, l = arguments.length; i < l; i++) {a = a * arguments[i];}return a; };var proxyMult = (function () { var cache = {}; return function () { var args = Array.prototype.join.call(arguments, ', '); if (args in cache) { return cache[args]; } return cache[args] = mult.apply(this, arguments); } })(); proxyMult(1, 2, 3, 4); // 輸出:24 proxyMult( 1, 2, 3, 4 ); // 輸出:24代理模式的適用場合
虛擬代理是一種優化模式。如果有些類或對象需要使用大量內存保存其數據,而你并不需要在實例化后立即訪問這些數據, 或者, 構造函數需要進行大量計算,此時需要使用虛擬代理模式。
優缺點
優點
控制開銷較大的對象的創建時機。
缺點
代理可以隱藏大量復雜行為。
總結
以上是生活随笔為你收集整理的javascript设计模式-代理模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android contentprovi
- 下一篇: 小白上路之markdown编辑器学习使用