摘要:實(shí)際上在這種將函數(shù)作為一等對象的語言里,策略模式已經(jīng)融入到了語言本身當(dāng)中,我們經(jīng)常使用高階函數(shù)來封裝不同的行為,并且把它傳遞到另一個函數(shù)中。
聲明:這個系列為閱讀《JavaScript設(shè)計模式與開發(fā)實(shí)踐》 ----曾探@著一書的讀書筆記
1.策略模式的定義將不變的部分和變化的部分隔開是每個設(shè)計模式的主題。
2.策略模式的目的定義一系列的算法,把它們一個個封裝起來,并且使它們可以相互替換。
將算法的使用與算法的實(shí)現(xiàn)分離開來。
3.傳統(tǒng)語言中的策略模式和JavaScript中的策略模式對比 3.1.傳統(tǒng)語言中的策略模式使用策略模式來實(shí)現(xiàn)計算獎金
var performances = function () {}; performances.prototype.calculate = function (salary) { return salary * 4; }; var performanceA =function () {}; performanceA.prototype.calculate=function (salary) { return salary * 3; }; var performanceB =function () {}; performanceB.prototype.calculate=function (salary) { return salary * 2; }; //定義獎金類Bonus var Bonus =function () { this.salary = null; //原始工資 this.strategy = null;//績效等級對應(yīng)的策略對象 }; Bonus.prototype.setSalary=function (salary) { this.salary=salary; //設(shè)置員工的原始工資 }; Bonus.prototype.setStrategy=function (strategy) { this.strategy=strategy;//設(shè)置績效等級對應(yīng)的策略對象 }; Bonus.prototype.getBonus =function () { //取得獎金數(shù)額 return this.strategy.calculate(this.salary);//把計算獎金的操作委托給對應(yīng)的策略對象 }; var bonus = new Bonus(); bonus.setSalary(10000); bonus.setStrategy(new performances());//設(shè)置策略對象 console.log(bonus.getBonus()); bonus.setStrategy(new performanceA()); console.log(bonus.getBonus());
定義有系列的算法,把它們各自封裝成策略類,算法被封裝在策略類內(nèi)部的方法里。在客戶端對Context發(fā)起請求的時候,Context總是把請求委托給這些策略對象中間的某一個進(jìn)行計算。
3.2.JavaScript中的策略模式//封裝的策略算法 var strategies={ "S":function (salary) { return salary * 4; }, "A":function (salary) { return salary * 3; }, "B":function (salary) { return salary * 2; } }; //具體的計算方法 var calculateBonus=function (level, salary) { return strategies[level](salary); }; console.log(calculateBonus("S",1000)); console.log(calculateBonus("A",4000));
使用策略模式重構(gòu)代碼,可以消除程序中大片的條件分支語句。在實(shí)際開發(fā)中,我們通常會把算法的含義擴(kuò)散開來,使策略模式也可以用來封裝一系列的“業(yè)務(wù)規(guī)則”。只要這些業(yè)務(wù)規(guī)則指向的目標(biāo)一致,并且可以被替換使用,我們就可以使用策略模式來封裝他們。
4.策略模式實(shí)現(xiàn)的表單校驗(yàn) 4.1使用JavaScript來實(shí)現(xiàn)的一個支持多重校驗(yàn)規(guī)則表單校驗(yàn)//策略對象 var strategies = { isNonEmpty: function (value, errorMsg){ if (value === "") { return errorMsg; } }, minLength: function (value, length, errorMg){ if (value.length < length) { return errorMg; } }, isMobile: function (value, errorMsg){ if (!/(^1[3|5|8][0-9]{9}$)/.test(value)) { return errorMsg; } } }; /** * Validator 類 * @constructor */ var Validator = function (){ this.cache = []; }; Validator.prototype.add = function (dom, rules){ var self = this; for (var i = 0, rule; rule = rules[i++];) { (function (rule){ var strategyAry=rule.strategy.split(":"); var errorMsg=rule.errorMsg; self.cache.push(function (){ var strategy=strategyAry.shift(); strategyAry.unshift(dom.value); strategyAry.push(errorMsg); return strategies[strategy].apply(dom,strategyAry); }) })(rule) } }; Validator.prototype.start=function (){ for (var i=0,validatorFunc;validatorFunc=this.cache[i++];){ var errorMsg=validatorFunc(); if(errorMsg){ return errorMsg; } } }; //客戶端調(diào)用的代碼 var registerForm=document.getElementById("registerForm"); var validataFunc=function (){ var validator=new Validator(); validator.add(registerForm.userName,[{ "strategy":"isNonEnpty", "errorMsg":"用戶名不能為空" },{ "strategy":"minLength", "errorMsg":"用戶名長度不能小于10位" }]); // validator.add(registerForm.password,[]) var errorMsg =validator.start(); return errorMsg; }; registerForm.onsubmit=function (){ var errorMsg=validataFunc(); if(errorMsg){ alert(errorMsg); return false; } };4.2策略模式的優(yōu)缺點(diǎn):
優(yōu)點(diǎn):
策略模式利用組合,委托和多態(tài)等技術(shù)思想,可以有效的避免多重條件選擇語句;
策略模式提供了對開放-封閉原則的完美支持,將算法封裝在獨(dú)立的strategy中,使得它們易于切換,易于理解,易于擴(kuò)展。
策略模式中的算法也可以復(fù)用在系統(tǒng)的其它地方,從而避免許多重復(fù)的復(fù)制粘貼工作。
在策略模式中利用組合和委托來讓Context擁有執(zhí)行算法的能力,這也是繼承的一種更輕便的替代方案。
缺點(diǎn):
策略模式會在程序中添加許多的策略類和策略對象
要使用策略模式,就必須要了解各個strategy和他們之間的不同點(diǎn),這樣才能選擇一個合適的strategy。
4.3函數(shù)多態(tài)性的描述在函數(shù)作為一等對象的語言中,策略模式是隱形的。strategy就是值為函數(shù)的變量。
在JavaScript中,除了使用類來封裝算法和行為之外,使用函數(shù)當(dāng)然也是一種選擇。這些“算法”可以被封裝到函數(shù)中并且四處傳遞,也就是我們常說的“高階函數(shù)”。
實(shí)際上在JavaScript這種將函數(shù)作為一等對象的語言里,策略模式已經(jīng)融入到了語言本身當(dāng)中,我們經(jīng)常使用高階函數(shù)來封裝不同的行為,并且把它傳遞到另一個函數(shù)中。當(dāng)我們對這些函數(shù)發(fā)出“調(diào)用”的消息時,不同的函數(shù)會返回不同的執(zhí)行結(jié)果。所以在JavaScript中,“函數(shù)對象的多態(tài)性”會更加簡單些。
總結(jié):在JavaScript語言的策略模式中,策略類往往被函數(shù)所代替,這時策略模式就成了一種“隱形”的模式。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/86430.html
摘要:策略模式實(shí)現(xiàn)的也是類似的場景。第二個部分是環(huán)境類不變,接收客戶的請求,隨后把請求委托給某一個策略類。參考文章設(shè)計模式設(shè)計模式與開發(fā)實(shí)踐設(shè)計模式系統(tǒng)講解與應(yīng)用本文首發(fā),期待作者以樂之名本文原創(chuàng),有不當(dāng)?shù)牡胤綒g迎指出。 showImg(https://segmentfault.com/img/bVbugi7?w=800&h=600); 策略模式:定義一系列的算法,把它們一個個封裝起來,并且...
摘要:本系列為設(shè)計模式與開發(fā)實(shí)踐作者曾探學(xué)習(xí)總結(jié),如想深入了解,請支持作者原版策略模式策略模式的定義定義一系列的算法,把它們一個個封裝起來,并且使它們可以互相替換。 本系列為《JavaScript設(shè)計模式與開發(fā)實(shí)踐》(作者:曾探)學(xué)習(xí)總結(jié),如想深入了解,請支持作者原版 策略模式 策略模式的定義:定義一系列的算法,把它們一個個封裝起來,并且使它們可以互相替換。 舉個形象的例子,使用策略模式計算...
摘要:策略模式可以避免代碼中的多重判斷條件。策略模式在程序中或多或少的增加了策略類。此文僅記錄本人閱讀設(shè)計模式與開發(fā)實(shí)踐這個本時的感受,感謝作者曾探寫出這么好的一本書。設(shè)計模式中很重要的一點(diǎn)就是將不變和變分離出來。參考設(shè)計模式與開發(fā)實(shí)踐曾探 策略模式的定義是:定義一系列的算法,把它們一個個封裝起來,并且是它們可以相互替換。 策略模式可以避免代碼中的多重判斷條件。 策略模式很好的體現(xiàn)了開放-...
摘要:設(shè)計模式與開發(fā)實(shí)踐讀書筆記。策略模式可以有效避免多重條件選擇語句。當(dāng)然,策略模式也有一些缺點(diǎn)增加了許多策略類或者策略對象。要使用策略模式,必須了解所有的,違反了最少知識原則。至此,回家咯附設(shè)計模式之發(fā)布訂閱模式觀察者模式 《JavaScript設(shè)計模式與開發(fā)實(shí)踐》讀書筆記。這本書挺好的,推薦。 俗話說,條條大路通羅馬。在現(xiàn)實(shí)生活中,我們可以采用很多方法實(shí)現(xiàn)同一個目標(biāo)。比如我們先定個小目...
閱讀 2140·2021-11-23 09:51
閱讀 3401·2021-09-28 09:36
閱讀 1231·2021-09-08 09:35
閱讀 1901·2021-07-23 10:23
閱讀 3379·2019-08-30 15:54
閱讀 3061·2019-08-29 17:05
閱讀 509·2019-08-29 13:23
閱讀 1365·2019-08-28 17:51