您好,登錄后才能下訂單哦!
這篇文章主要講解了“javascript設計模式中的策略模式怎么實現”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“javascript設計模式中的策略模式怎么實現”吧!
策略模式的定義:定義一系列的算法,將他們一個個封裝起來,使他們直接可以相互替換。
策略模式是開發中常用的第二種設計模式,它在開發中非常常見,由兩部分組成。第一部分是策略類,封裝了許多具體的,相似的算法。第二部分是環境類,接受客戶請求,隨后將請求委托給策略類。說的通俗一點就是將相同算法的函數存放在一個包裝里邊,每個函數用相同的方式拿出來,就叫做策略模式。下面我們來通過代碼實現深入了解一下。
假如需要實現一個計算員工獎金的程序,效績為 S 則發基本工資的4倍,A 則3倍,以此類推,那么我們正常實現該代碼,是通過判斷分支語句來實現。
1. 通過分支實現
let bonus = function (performance, salary) { if(performance === "S") { return salary*4; } if(performance === "A") { return salary*3; } if(performance === "B") { return salary*2; } }
分析:該實現存在顯著的缺點,如果隨著效績 的擴展,比如增加C,D,E, if 分支不斷累加,使得代碼越來越龐大。
因此我們使用策略模式來重構代碼。
2.使用策略模式實現
let performanceS = function () {}; performanceS.prototype.calculate = function ( salary ) { return salary*4 } let performanceA = function () {}; performanceA.prototype.calculate = function ( salary ) { return salary*3 } let performanceB = function () {}; performanceB.prototype.calculate = function ( salary ) { return salary*2 } let performanceC = function () {}; performanceC.prototype.calculate = function ( salary ) { return salary*1 } let Bonus = function () { this.salary = null; // 原始工資 this.strategy = null; // 原始績效 } Bonus.prototype.setSalary = function ( salary ) { this.salary = salary; } Bonus.prototype.setStrategy = function ( strategy ) { this.strategy = strategy; } Bonus.prototype.getBonus = function () { if(!this.strategy) { throw new Error("未設置績效"); } return this.strategy.calculate(this.salary); } let bonus = new Bonus(); bonus.setSalary(10000); bonus.setStrategy(new performanceS()); console.log(bonus.getBonus());
分析:重構后,我們將每種績效算法單獨成一個函數,需要計算某種績效時只需要將其傳入 getBonus 函數中,去掉了 if 分支,減少了性能消耗,并且使代碼有了彈性,隨時增加其他績效,不需要更改原代碼。
主要思想:這段代碼基于面向對象語言,引入了多態的概念,不適用于js。
3. JavaScript 版本的策略模式
// js中函數也是對象,直接將 strategy 定義為函數 let strategy = { "S": function ( salary ){ return salary*4; }, "A": function ( salary ) { return salary*3; }, "B": function ( salary ) { return salary*2; } } let calculateBonus = function ( level, salary ) { return strategy[ level ]( salary ); } console.log(calculateBonus('A', 20000)) // 6000
分析:js 的對象可以直接創建,將函數封裝進去,這樣一來,代碼顯得清晰簡潔。代碼的復用,彈性也隨之變強。
以上就是 js 設計模式策略模式的主要思想和實現,他在應用中有兩個主要的作用,一是策略模式實現晃動動畫;二是實現表單驗證,有能力有興趣的小伙伴可以往下看。
1. 使用策略模式實現緩存動畫
// 緩動算法 let tween = { linear (t, b, c, d) { return c*t/d + b; }, easeIn (t, b, c, d) { return c*(t /= d) *t + b; }, strongEaseIn (t, b, c, d) { return c*(t /= d) *t *t *t *t + b; } } // 定義一個動畫類,參數為要運動的 dom 節點 let Animate = function ( dom ) { this.dom = dom; this.startTime = 0; this.startPos = 0; this.endPos = 0; this.propertyName = null; this.easing = null; // 緩動算法 this.duration = null; } // 啟動方法 Animate.prototype.start = function (propertyName, endPos, duration, easing) { this.startTime =+ new Date; this.startPos = this.dom.getBoundingClientRect()[propertyName]; // dom 初始位置 this.propertyName = propertyName; this.endPos = endPos; this.duration = duration; this.easing = tween[easing]; let self = this; let timeId = setInterval(() => { if( self.step() === false){ clearInterval(timeId); } }, 19); } // 實現小球每一幀要做的事情 Animate.prototype.step = function () { let t =+ new Date; if(t>this.startTime + this.duration){ this.update(this.endPos); return false; } let pos = this.easing(t - this.startTime, this.startPos, this.endPos - this.startPos, this.duration); this.update(pos); } Animate.prototype.update = function (pos) { this.dom.style[this.propertyName] = pos + 'px'; } let test = function () { let div = document.getElementById('div'); let animate = new Animate(div); animate.start('left', 500, 1000, 'strongEaseIn'); // animate.start('top', 1500, 500, 'strongEaseIn'); } test();
2. 使用策略模式進行表單驗證
let strategies = { isNonEmpty ( value, errorMsg) { // 判斷是否為空 if(value === '') { return errorMsg; } }, minLength (value, length, errorMsg){ if (value.length < length) { return errorMsg; } } } let dom = document.forms[0].acount; let validatarFunc = function () { let validator = new Validator(); // 添加校驗規則 validator.add(dom, 'isNonEmpty', '用戶名不能為空!'); let errorMsg = validator.start(); return errorMsg; // 返回校驗結果 } // 實現表單校驗保存類 let Validator = function () { this.cache = []; // 保存校驗規則 } Validator.prototype.add = function (dom, rule, errorMsg) { let ary = rule.split(':'); this.cache.push( function(){ let strategy = ary.shift(); ary.unshift(dom.value); ary.push( errorMsg ); return strategies[strategy].apply(dom, ary); }) } Validator.prototype.start = function () { for(let i = 0, validatorFunc; validatorFunc = this.cache[i++];){ let msg = validatorFunc(); if( msg ) { return msg; } } } document.forms[0].addEventListener('submit', (e) =>{ let errorMsg = validatarFunc(); if(errorMsg){ alert(errorMsg); e.preventDefault(); } })
分析:第一個實現中是把緩動算法封裝在一個對象中,調用他們時便于相互替換,也便于擴展。
第二個實現是將校驗規則封裝起來。
感謝各位的閱讀,以上就是“javascript設計模式中的策略模式怎么實現”的內容了,經過本文的學習后,相信大家對javascript設計模式中的策略模式怎么實現這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。