最近2018中文字幕在日韩欧美国产成人片_国产日韩精品一区二区在线_在线观看成年美女黄网色视频_国产精品一区三区五区_国产精彩刺激乱对白_看黄色黄大色黄片免费_人人超碰自拍cao_国产高清av在线_亚洲精品电影av_日韩美女尤物视频网站

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
JavaScript策略模式如何實(shí)現(xiàn)

這篇文章主要介紹“JavaScript策略模式如何實(shí)現(xiàn)”,在日常操作中,相信很多人在JavaScript策略模式如何實(shí)現(xiàn)問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”JavaScript策略模式如何實(shí)現(xiàn)”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!

橋西網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)!從網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、成都響應(yīng)式網(wǎng)站建設(shè)公司等網(wǎng)站項(xiàng)目制作,到程序開發(fā),運(yùn)營(yíng)維護(hù)。創(chuàng)新互聯(lián)成立于2013年到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)。

策略模式:定義了一系列家族算法,并對(duì)每一種算法單獨(dú)封裝起來,讓算法之間可以相互替換,獨(dú)立于使用算法的客戶。

通常我并不會(huì)記得“牛頓***定律”的具體內(nèi)容,所以我也難保證我會(huì)對(duì)這個(gè)定義記得多久……用FE經(jīng)常見到的東西來舉個(gè)例子說明一下:

$("div").animation({left: '50px'},1000,'easein');  $("div").animation({left: '50px'},1000,'linear');  $("div").animation({left: '50px'},1000,'swing');  //看***三個(gè)關(guān)于動(dòng)畫效果的參數(shù)  //Jquery文檔總提到easing(第三個(gè)參數(shù)):要使用的擦除效果的名稱(需要插件支持).默認(rèn)jQuery提供"linear" 和 "swing".

我們?cè)趯?duì)元素設(shè)置動(dòng)畫的緩動(dòng)效果,實(shí)際就是策略模式的一種實(shí)現(xiàn)。這樣的緩動(dòng)算法跟我們使用Jquery的人來說沒有直接關(guān)系,假如我的項(xiàng)目中某個(gè)動(dòng) 畫需要一種新的算法效果,那么我們?cè)偃ラ_發(fā)一個(gè)插件就好了。反之,如果Jquery沒有提供這樣一種插件機(jī)制,那針對(duì)需求變化難不成要去改動(dòng)Jquery 的源碼嗎?

在《大話設(shè)計(jì)模式》一書中,作者舉例的是一個(gè)商場(chǎng)的收銀系統(tǒng),在實(shí)際操作中,商場(chǎng)可能因?yàn)椤半p11買一送一”、“滿500立減50”、“中秋節(jié)全場(chǎng) 11折”等活動(dòng)而對(duì)最終的收費(fèi)產(chǎn)生變化。如果哪一天商場(chǎng)突然倒閉,全場(chǎng)兩元,這時(shí)候我們僅需要給軟件系統(tǒng)增加一個(gè)所有商品價(jià)格變兩元的插件算法(類)即 可。

我先來模擬一下策略模式的基本代碼形態(tài):

            Document                function ConcreteStrategyA(){             this.AlgorithmInterface = function(){                 console.log("算法A");             }         }          function ConcreteStrategyB(){             this.AlgorithmInterface = function(){                 console.log("算法B");             }         }          function ConcreteStrategyC(){             this.AlgorithmInterface = function(){                 console.log("算法C");             }         }          //Context,用一個(gè)createStrategy來配置,維護(hù)一個(gè)對(duì)Strategy對(duì)象的引用          function Context(strategy){             this.strategy = strategy;             this.ContextInterface = function(){                 strategy.AlgorithmInterface();             }          }          //應(yīng)用         var context1 = new Context(new ConcreteStrategyA());         context1.ContextInterface();          var context2 = new Context(new ConcreteStrategyB());         context2.ContextInterface();          var context3 = new Context(new ConcreteStrategyC());         context3.ContextInterface();       

通常來說,具體的某一種算法必須保證實(shí)現(xiàn)了某一些接口或者繼承某個(gè)抽象類,才不會(huì)發(fā)生類型錯(cuò)誤,在javascript中去實(shí)現(xiàn)接口、抽象類、繼承等特性要費(fèi)一些周章,所以我這個(gè)例子是不嚴(yán)謹(jǐn)?shù)模瑑H從最簡(jiǎn)單的實(shí)現(xiàn)方式著手。

具體實(shí)現(xiàn)一個(gè)商場(chǎng)收銀系統(tǒng):包括一個(gè)單獨(dú)js文件,和一個(gè)具體的實(shí)現(xiàn)html文件

//因?yàn)橐玫綌?shù)值驗(yàn)證,所以...這里用的是jquery2.1里面的isNum function isNum(obj){     return obj - parseFloat(obj)>=0; } //算法A,沒有活動(dòng),正常收費(fèi) function ConcreteStrategyA(){     this.AlgorithmInterface = function(money){         return money;     } } //算法B,滿300減100 function ConcreteStrategyB(MoneyCondition,MoneyReturn){     this.MoneyCondition = MoneyCondition,     this.MoneyReturn    = MoneyReturn;      this.AlgorithmInterface = function(money){         var result=money;         if(money>=MoneyCondition){             result = money - Math.floor(money/MoneyCondition)*MoneyReturn;         }         return result;     } } //算法C,打折 function ConcreteStrategyC(moneyRebate){     this.moneyRebate = moneyRebate;     this.AlgorithmInterface = function(money){         return money*this.moneyRebate;     } }  //Context,用一個(gè)createStrategy來配置,維護(hù)一個(gè)對(duì)Strategy對(duì)象的引用 //這里將算法相關(guān)的從客戶端剝離出來,簡(jiǎn)單工廠模式 function Context(type){     this.strategy = null;     switch(type){         case "a":             this.strategy = new ConcreteStrategyA();             break;         case "b":             this.strategy = new ConcreteStrategyB("300","100");             break;         case "c":             this.strategy = new ConcreteStrategyC("0.8");             break;     }      this.ContextInterface = function(money){         if(!isNum(money)){             money = 0;         }         return this.strategy.AlgorithmInterface(money);     }  }

HTML部分:

            Document              .block {             padding:5px 0;             border-bottom:1px solid #ccc;         }         .menu {margin:10px auto;text-align: center;}                          
                   
     
              
                   var tPrice = document.getElementsByClassName("tPrice"),             tNum   = document.getElementsByClassName("tNum"),             tAlg   = document.getElementsByClassName("tAlg"),             tMoney = document.getElementsByClassName("tMoney"),             total  = document.querySelector("#total");          var addBtn = document.querySelector("#addBtn");         addBtn.addEventListener("click",function(){             var html = '';             var div = document.createElement("div");             div.className="block";             div.innerHTML = html;             this.parentNode.parentNode.insertBefore(div,this.parentNode);         })                   function calculate(e){              //根據(jù)事件對(duì)象判斷事件源,獲取同類元素中的位置             var num = 0,className = e.target.className;             switch(className){                 case "tPrice":                     for(var i=tPrice.length-1;i>=0;i--){                         if(tPrice[i]==e.target){                             num = i;                         }                     }                     break;                 case "tNum":                     for(var i=tNum.length-1;i>=0;i--){                         if(tNum[i]==e.target){                             num = i;                         }                     }                     break;                 case "tAlg":                     for(var i=tAlg.length-1;i>=0;i--){                         if(tAlg[i]==e.target){                             num = i;                         }                     }                     break;                 default:                     return;             }               var context = new Context(tAlg[num].value);             var money   = 0;             var totalValue = 0;              money = context.ContextInterface(tPrice[num].value*tNum[num].value);              tMoney[num].value = money;              for(var index=0,len=tMoney.length;index  

最開始我對(duì)商品單價(jià)、數(shù)量、計(jì)算方式僅提供一個(gè)可操作的地方,這也是《大話設(shè)計(jì)模式》一書中產(chǎn)品的基本形態(tài),考慮到更良好交互性,我增加了一個(gè)按 鈕,可以增加更多行。這帶來的一點(diǎn)小問題就是:起初我只需要為幾個(gè)元素綁定事件即可,現(xiàn)在要對(duì)可能產(chǎn)生的更多元素綁定事件,所以我就選擇了“事件代理”, 獲得發(fā)生事件的元素位置,改變同一行中的相應(yīng)元素的值,對(duì)于總價(jià),則總是遍歷所有的單行總價(jià)相加。

BTW,在獲取元素的時(shí)候使用了getElementsByClassName而沒有使用querySelectorAll,是因?yàn)楹笳攉@取的不是一個(gè)動(dòng)態(tài)集合。

接著我嘗試將昨天學(xué)習(xí)的觀察者設(shè)計(jì)模式與策略模式混合起來,起初我是這樣做的....

            Document              .block {             padding:5px 0;             border-bottom:1px solid #ccc;         }         .menu {margin:10px auto;text-align: center;}                          
                   
     
              
                    //發(fā)布者         function Publisher(obj){             this.observers = [];             var number = 0;              this.getState=function(){                 return number;             }             this.setState = function(num){                 number = num;                 this.notice();             }         }         Publisher.prototype.addOb=function(observer){             var flag = false;             for (var i = this.observers.length - 1; i >= 0; i--) {                 if(this.observers[i]===observer){                     flag=true;                               }             };             if(!flag){                 this.observers.push(observer);             }             return this;         }          Publisher.prototype.removeOb=function(observer){             var observers = this.observers;             for (var i = 0; i < observers.length; i++) {                 if(observers[i]===observer){                     observers.splice(i,1);                 }             };             return this;         }         Publisher.prototype.notice=function(){             var observers = this.observers;             for (var i = 0; i < observers.length; i++) {                     observers[i].update(this.getState());             };         }          //訂閱者         function Subscribe(obj){             this.obj = obj;             this.update = function(data){                 this.obj.value = data;             };         }          //實(shí)際應(yīng)用         var tPrice = document.getElementsByClassName("tPrice"),             tNum   = document.getElementsByClassName("tNum"),             tAlg   = document.getElementsByClassName("tAlg");          var pba = new Publisher(document);          var oba = new Subscribe(document.getElementsByClassName("tMoney"));         var obb = new Subscribe(document.querySelector("#total"));           pba.addOb(oba).addOb(obb);          oba.update = function(num){             var context = new Context(tAlg[num].value);             var money   = 0;              money = context.ContextInterface(tPrice[num].value*tNum[num].value);              this.obj[num].value = money;         }         obb.update = function(num){             var totalValue = 0,                 tMoney = document.getElementsByClassName("tMoney");             for(var index=0,len=tMoney.length;index';             var div = document.createElement("div");             div.className="block";             div.innerHTML = html;             this.parentNode.parentNode.insertBefore(div,this.parentNode);         })                   function calculate(e){               //根據(jù)事件對(duì)象判斷事件源,獲取同類元素中的位置             var num = 0,className = e.target.className;             switch(className){                 case "tPrice":                     for(var i=tPrice.length-1;i>=0;i--){                         if(tPrice[i]==e.target){                             num = i;                         }                     }                     break;                 case "tNum":                     for(var i=tNum.length-1;i>=0;i--){                         if(tNum[i]==e.target){                             num = i;                         }                     }                     break;                 case "tAlg":                     for(var i=tAlg.length-1;i>=0;i--){                         if(tAlg[i]==e.target){                             num = i;                         }                     }                     break;                 default:                     return;             }             pba.setState(num);         }          document.addEventListener('keyup',calculate,false);         document.addEventListener('change',calculate,false);       

我在之前學(xué)習(xí)觀察者模式的時(shí)候,僅僅是對(duì)DOM元素進(jìn)行了發(fā)布者與訂閱者的區(qū)分,卻不知道也沒有思考過數(shù)據(jù)、視圖與控制器這種結(jié)構(gòu)中的發(fā)布者與訂閱 者區(qū)分,所以還是要多看看不同的案例。學(xué)習(xí)完這篇文章以后,我依葫蘆畫瓢對(duì)我這個(gè)“收銀系統(tǒng)”也弄一下,但是我畢竟還沒有學(xué)“組合模式”,所以我也不打算 再寫一個(gè)Controller,僅僅是Model和View之間加入觀察者模式。***的結(jié)果是這樣的:

            Document              .block {             padding:5px 0;             border-bottom:1px solid #ccc;         }         .menu {margin:10px auto;text-align: center;}                          
                   
     
              
                    //實(shí)現(xiàn)了觀察者的Event類         function Event(pub){             this._pub = pub;             this._listener = [];         }         Event.prototype = {             attach: function(listener){                 this._listener.push(listener);             },             notify: function(num){                 for(var i=0;i=0;i--){                     if(elements[i]===target){                         a = i;                     }                 }                 switch(className){                     case "tPrice":                         b = 0;                         break;                     case "tNum":                         b = 1;                         break;                     case "tMoney":                         b = 3;                         break;                 }                 if(!isNum(a)){                     a = 0;                 }                 if(!isNum(b)){                     b = 0;                 }                 that._model.itemChange([a,b],target.value);             });             this._ele.eTarget.addEventListener('change',function(e){                 var target = e.target,                     className = target.className;                 if(target.nodeName.toLowerCase()!=="select"){                     return;                 }                 var elements = document.getElementsByClassName(className),                     a;                 for(var i=elements.length-1;i>=0;i--){                     if(elements[i]===target){                         a = i;                     }                 }                 that._model.itemChange([a,2],target.value);             });             this._ele.addBtn.addEventListener('click',function(){                 var html = '';                 var div = document.createElement("div");                 div.className="block";                 div.innerHTML = html;                 this.parentNode.parentNode.insertBefore(div,this.parentNode);                  that._model.itemAdd([0,0,"a",0]);             });         }         View.prototype.getTotal= function(pub,num){             var price = this._model._data[num][0],                 number = this._model._data[num][1],                 alg = this._model._data[num][2],                 money = this._model._data[num][3];              var context = new Context(alg);             money = context.ContextInterface(price*number);             this._model._data[num][3]=money;              var total = 0;             for(var i=0;i  

在形成上面的最終結(jié)果途中,在對(duì)數(shù)據(jù)進(jìn)行計(jì)算并且將結(jié)果傳遞給Model時(shí),我用了會(huì)觸發(fā)觀察者模式更新內(nèi)容的函數(shù),從而導(dǎo)致在一次計(jì)算以后又更新 又計(jì)算又更新的***循環(huán)中,改為直接對(duì)Model中的數(shù)據(jù)進(jìn)行操作就沒事了。

到此,關(guān)于“JavaScript策略模式如何實(shí)現(xiàn)”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!


網(wǎng)頁標(biāo)題:JavaScript策略模式如何實(shí)現(xiàn)
文章轉(zhuǎn)載:http://fisionsoft.com.cn/article/jooigc.html