詳解javascript設(shè)計(jì)模式三:代理模式
代理模式是一種對(duì)程序?qū)ο筮M(jìn)行控制性訪問的一類解決方案。
引入代理模式,其實(shí)是為了實(shí)現(xiàn)單一職責(zé)的面向?qū)ο笤O(shè)計(jì)原則。
單一職責(zé)其實(shí)就是指在一個(gè)類中(js中通常指對(duì)象和函數(shù)等),應(yīng)僅有一個(gè)引起它變化的原因。這樣會(huì)幫助程序設(shè)計(jì)具有良好的健壯和高內(nèi)聚特性,從而當(dāng)變化發(fā)生時(shí),程序設(shè)計(jì)會(huì)盡量少的受到意外破壞。
代理模式有多種方法,保護(hù)代理、遠(yuǎn)程代理、虛擬代理、緩存代理等。
但在javascript中,代理模式最常用到的兩種方法是虛擬代理和緩存代理。
虛擬代理
在理解虛擬代理時(shí),可以將其想象為一個(gè)經(jīng)紀(jì)人,客戶程序需要通過這個(gè)虛擬代理(經(jīng)紀(jì)人)來調(diào)用本體對(duì)象的方法。
虛擬代理示例demo1: 圖片loading預(yù)加載
//通過虛擬代理實(shí)現(xiàn)圖片預(yù)加載 //代理模式進(jìn)行圖片預(yù)加載的實(shí)現(xiàn)思路是: 通過代理對(duì)象獲取實(shí)際顯示圖片地址并進(jìn)行加載,同時(shí)先讓本體對(duì)象顯示預(yù)加載圖片,待代理對(duì)象將實(shí)際圖片地址加載完畢后傳遞給本體對(duì)象進(jìn)行顯示即可。 //本體對(duì)象 var myImage = (function(){ var imgNode = new Image() document.body.appendChild(imgNode) return { setSrc: function(src){ imgNode.src = src } } })() //代理對(duì)象 var proxyImage = (function(){ var img = new Image(); //1、代理對(duì)象新建一個(gè)img對(duì)象 img.onload = function(){ //4、代理對(duì)象img加載真實(shí)圖片src完成后將src傳遞給本體對(duì)象顯示 myImage.setSrc(this.src) } return { setProxySrc: function(src){ myImage.setSrc('../images/loding.gif') //2、代理對(duì)象控制本體對(duì)象使用加載圖片src img.src = src //3、代理對(duì)象的img對(duì)象獲取將要傳遞給本體對(duì)象的真實(shí)圖片src } } })() //通過代理對(duì)象來對(duì)本體對(duì)象進(jìn)行訪問 proxyImage.setProxySrc('https://p1.ssl.qhimgs1.com/t0153297036f4471d81.jpg')
虛擬代理示例demo2:合并HTTP請(qǐng)求,減少網(wǎng)絡(luò)請(qǐng)求資源消耗
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>代理模式 虛擬代理合并HTTP請(qǐng)求</title> </head> <body> <div> <input type="checkbox" id="1" />1 <input type="checkbox" id="2" />2 <input type="checkbox" id="3" />3 <input type="checkbox" id="4" />4 <input type="checkbox" id="5" />5 <input type="checkbox" id="6" />6 <input type="checkbox" id="7" />7 <input type="checkbox" id="8" />8 <input type="checkbox" id="9" />9 </div> </body> <script> //使用 //本體對(duì)象 var synchornurFile = function(id){ console.log('開始同步:' + id); } var proxySynchornurFile = (function(){ var cache = [], //集合一段時(shí)間內(nèi)需要同步的id timer; //定時(shí)器 return function(id){ cache.push(id) if(timer){ //保證不會(huì)覆蓋已經(jīng)啟動(dòng)的定時(shí)器 return } timer = setTimeout(function(){ synchornurFile(cache.join(',')) clearTimeout(timer) timer = null cache.length = 0 }, 2000) } })() var check = document.getElementsByTagName('input') for(var i=0; i<check.length; i++){ check[i].onclick = function(){ if(this.checked === true){ proxySynchornurFile(this.id) } } } </script> </html>
緩存代理
緩存代理可以為一些開銷大的運(yùn)算結(jié)果提供暫時(shí)存儲(chǔ),在下次運(yùn)算時(shí),如果傳遞進(jìn)來的參數(shù)和之前的一致,則可以直接返回前面存儲(chǔ)的結(jié)果
緩存代理示例demo: 計(jì)算乘積
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>代理模式-緩存代理</title> </head> <body> <input type="text" id="input1">* <input type="text" id="input2"> <div id="result"></div> <button type="button" id="btn">計(jì)算</button> </body> <script> //緩存代理示例: 計(jì)算乘積 //本體對(duì)象 var calculate = function(){ var a = 1; for(var i=0; i<arguments.length; i++){ a = a*arguments[i] } return a; } //代理對(duì)象,創(chuàng)建緩存代理的工廠,參數(shù)fn可以為任意需要進(jìn)行代理的函數(shù),除了上述計(jì)算乘積的本體對(duì)象函數(shù)外,還可以是計(jì)算加減或進(jìn)行其他操作的本體函數(shù) var proxyCalculate = function(fn){ var resultCache = {}; return function(){ var args = Array.prototype.join.call(arguments, ',') if(args in resultCache){ //測(cè)試對(duì)象中是否有對(duì)應(yīng)的name,有則直接返回該name的值 return resultCache[args] } return resultCache[args] = fn.apply(this, arguments) } } document.getElementById('btn').onclick = function(){ var v1 = document.getElementById('input1').value var v2 = document.getElementById('input2').value var result = proxyCalculate(calculate)(v1, v2) document.getElementById('result').innerHTML = result } //總結(jié): 代理模式還有多種,比如保護(hù)代理、遠(yuǎn)程代理等,但js中常用的代理模式有虛擬代理和緩存代理兩種。 </script> </html>
在編寫業(yè)務(wù)代碼時(shí),并不需要一開始就考慮是否使用代理模式,只要當(dāng)發(fā)現(xiàn)使用代理模式更方便時(shí),再編寫代理對(duì)象即可。
以上所述是小編給大家介紹的javascript設(shè)計(jì)模式三:代理模式詳解整合,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
JavaScript onkeydown事件入門實(shí)例(鍵盤某個(gè)按鍵被按下)
這篇文章主要介紹了JavaScript onkeydown事件入門實(shí)例,onkeydown事件捕捉鍵盤上某個(gè)按鍵被按下的情況,需要的朋友可以參考下2014-10-10JavaScript對(duì)象、屬性、事件手冊(cè)集合方便查詢
JavaScript對(duì)象、屬性、事件手冊(cè)查詢,對(duì)于學(xué)習(xí)js的朋友方便查找。2010-07-07JavaScript學(xué)習(xí)歷程和心得小結(jié)
在過去,JavaScript只是被用來做一些簡單的網(wǎng)頁效果,比如表單驗(yàn)證、浮動(dòng)廣告等,所以那時(shí)候JavaScript并沒有受到重視。2010-08-08javascript單引號(hào)和雙引號(hào)的區(qū)別和處理
這篇文章主要介紹了javascript單引號(hào)和雙引號(hào)的區(qū)別和處理,希望對(duì)大家有所幫助2014-05-05actionscript與javascript的區(qū)別
actionscript是flash的腳本語言,目前已經(jīng)由adobe公司升級(jí)到3.0版本,成為了真正意義的oop語言,JavaScript是由netscape工程師設(shè)計(jì)完成的一門腳本語言,用于web開發(fā)的前端腳本2011-05-05