摘要:將不變的部分和變化的部分分割開始每個設(shè)計模式的主題,策略模式的目的就是將算法的使用與算法的實現(xiàn)分離開來。結(jié)合策略模式,可以把判斷這一部分函數(shù)里提取出來重新封裝,提高代碼的復(fù)用性和可讀性。
最近在看《javascript設(shè)計模式與開發(fā)實踐》。
var calc = function(level,salary){ if(level === "A"){ return 3*salary } if(level === "B"){ return 2*salary } if(level === "C"){ return 1*salary } }
這段代碼看起來十分簡單,但是隨著后期的拓展,要添加更多的if語句,calc函數(shù)會變得更加龐大,不易于維護。
如果我要修改原有的計算分之,可能每次都要修改calc這個方法。實際上,這個calc這個方法的設(shè)計初衷只是為了返回 績效工資。
在整個代碼的其它部分,可能還需要這個計算方法,難道還要copy一份過去么,那么同樣的修改要修改兩塊代碼。
用策略模式來重構(gòu)代碼
策略模式指的是定義一系列的算法,把他們一個個都封裝起來。將不變的部分和變化的部分分割開始每個設(shè)計模式的主題,策略模式的目的就是將算法的使用與算法的實現(xiàn)分離開來。
再說上邊的需求,我們簡單思考下,其實變化的部分就是員工的等級和工資,而我們的目的就是返回績效工資這部分是不變的
// 根據(jù)員工的level和salary 金額的計算 var straigies = { “A”: function(salary){ return fn*3 }, “B”: function(salary){ return fn*2 }, “C”: function(salary){ return fn*1 } } //不變的部分 var calc = function(level,salary){ return straigies[level](salary) } // 執(zhí)行 calc("A",5000) // => 15000
比較下兩段代碼,不見了不友好的 if判斷,算法(策略)都放在了straigies 中,后續(xù)需求 只需要維護straigies對象即可。
用策略模式來重構(gòu)表單驗證
很多需要提交表單的業(yè)務(wù)場景,都需要如下結(jié)構(gòu)的代碼
$("submitBtn").on("click",functioin(){ if($name.value().length < 6){ console.log("用戶名長度不能少于6") } if($phone.value() != ""){ console.log("電話號碼不能為空") } ajaxFn() })
隨著 判斷條件的增加,函數(shù)的結(jié)構(gòu)會越來越臃腫龐大,而需要修改判斷的條件,就又要深入指定的if判斷去篩選,單純的新增規(guī)則在這個函數(shù)里,復(fù)用性太差。結(jié)合策略模式,可以把if判斷這一部分 函數(shù)里提取出來重新封裝,提高代碼的復(fù)用性和可讀性。
對代碼結(jié)構(gòu)的期望
$("submitBtn").on("click",functioin(){ var form = document.querySelector(".form"); var validator = new validator (); validator.addrules(form.username,"isNonEmpty","不能為空") validator.addrules(form.phone,"minLength:6","最少為6位") var erroMsg = validator.start(); if(erroMsg){ alert(validator); return false } ajaxFn() })
我們先封裝策略類
var stratigies = { isNonEmpty: function(value,erromsg){ if(value == ""){ return erromsg } }, minlength: function(value,length,erromsg){ if(value.length < length){ return erromsg } } }
封裝 驗證(validator類)
var Validator = function(){ this.cache = [] //用來緩存 } Validator.prototype.add = function(item,rule,erroMsg){ var arg = rule.split(":") // rule= > "isEmpty" => ["isEmpty"] || "minLength:5"=> ["minlength", “5”]; this.cache.push(function(){ var strategy = arg.shift(); // =>"isEmpty" || minLength arg.unshift(item.value); //[value] || [value,5] arg.push(errMsg)// [value,errMsg] || [value,5,errMsg] return stratigies[strategy].apply(item,arg) }) } //start方法就是遍歷這個Validator里緩存的方法并執(zhí)行 Validator.prototype.start = function(){ for(var i=0;i開始校驗, if(msg){ return msg // 如果msg有值 就說明驗證不通過,跳出循環(huán) } } }
此時,如果需要添加規(guī)則 或是修改驗證規(guī)則,就很簡單了
我們可以在stratigies里添加策略,也可以在 提交表單的函數(shù)里,新增或者修改規(guī)則
validator.addrules(form.phone,"minLength:6") =》 validator.addrules(form.phone,"minLength:10")
很蛋疼的是,對用戶名判斷只能一次輸入一種規(guī)則,如果需要加一種判斷規(guī)則,我就要在add一次strategy,
書中提供了進一步的拓展。
//預(yù)期 validator.addrules(form.username,[ { "erroMsg": "不能為空", "strategy": "isNonEmpty" }, { "erroMsg": "最小為6位", "strategy": "minLength:6" } ])
將策略用數(shù)組的方式傳入validator對象里,緩存在this.cache里,只需要調(diào)整對應(yīng)的add方法就可以
//old type Validator.prototype.add = function(item,rule,erroMsg){ var arg = rule.split(":") // rule= > "isEmpty" => ["isEmpty"] || "minLength:5"=> ["minlength", “5”]; this.cache.push(function(){ var strategy = arg.shift(); // =>"isEmpty" || minLength arg.unshift(item.value); //[value] || [value,5] arg.push(errMsg)// [value,errMsg] || [value,5,errMsg] return stratigies[strategy].apply(item,arg) }) } // new Type Validator.prototype.add = function(item,rules){ var _this = this; //保存this指針 for循環(huán)里的的自執(zhí)行函數(shù)的this指向window,用_this修復(fù)指針 //遍歷rules for(var i = 0;i"isEmpty" => ["isEmpty"] || "minLength:5"=> ["minlength", “5”]; var errMsg = rule.errMsg; _this.cache.push(function(){ var strategy = arg.shift(); // =>"isEmpty" || minLength arg.unshift(item.value); //[value] || [value,5] arg.push(errMsg)// [value,errMsg] || [value,5,errMsg] return stratigies[strategy].apply(item,arg) }) })(rule) } }
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/91098.html
摘要:訂閱模式的一個典型的應(yīng)用就是后面會寫一篇相關(guān)的讀書筆記。享元模式享元模式的核心思想是對象復(fù)用,減少對象數(shù)量,減少內(nèi)存開銷。適配器模式對目標函數(shù)進行數(shù)據(jù)參數(shù)轉(zhuǎn)化,使其符合目標函數(shù)所需要的格式。 設(shè)計模式 單例模式 JS的單例模式有別于傳統(tǒng)面向?qū)ο笳Z言的單例模式,js作為一門無類的語言。使用全局變量的模式來實現(xiàn)單例模式思想。js里面的單例又分為普通單例和惰性單例,惰性單例指的是只有這個實例...
摘要:設(shè)計模式與開發(fā)實踐讀書筆記。策略模式可以有效避免多重條件選擇語句。當然,策略模式也有一些缺點增加了許多策略類或者策略對象。要使用策略模式,必須了解所有的,違反了最少知識原則。至此,回家咯附設(shè)計模式之發(fā)布訂閱模式觀察者模式 《JavaScript設(shè)計模式與開發(fā)實踐》讀書筆記。這本書挺好的,推薦。 俗話說,條條大路通羅馬。在現(xiàn)實生活中,我們可以采用很多方法實現(xiàn)同一個目標。比如我們先定個小目...
摘要:在復(fù)雜的情況下,需要具體策略維護內(nèi)部狀態(tài)時,可能需要把策略和享元模式結(jié)合起來。函數(shù)比用戶定義的類的實例輕量,而且無需使用享元模式,因為各個策略函數(shù)在編譯模塊時只會創(chuàng)建一次。 一等函數(shù)實現(xiàn)設(shè)計模式 經(jīng)典的策略模式定義 定義一系列算法,把它們一一封裝起來,并且使它們可以相互替換。本模式使得算法可以獨立于使用它的客戶而變化。 案例 假如一個網(wǎng)店制定了下述折扣規(guī)則。 有 1000 或以上積分...
摘要:堆和方法區(qū)只有在程序運行時才能確定內(nèi)存的使用情況,垃圾回收器所關(guān)注的主要就是這部分內(nèi)存。虛擬機會根據(jù)當前系統(tǒng)的運行情況收集性能監(jiān)控信息,動態(tài)調(diào)整比率參數(shù)以提供最合適的停頓時間或最大的吞吐量。 Tip:內(nèi)容為對《深入理解Java虛擬機》(周志明 著)第三章內(nèi)容的總結(jié)和筆記。這是第一次拜讀時讀到的一些重點,做個分享,也為后面再次閱讀和實踐做保障。 3.1 概述 程序計數(shù)器、虛擬機棧、本地...
閱讀 3005·2021-10-12 10:12
閱讀 3052·2021-09-22 16:04
閱讀 3287·2019-08-30 15:54
閱讀 2602·2019-08-29 16:59
閱讀 2902·2019-08-29 16:08
閱讀 868·2019-08-29 11:20
閱讀 3492·2019-08-28 18:08
閱讀 648·2019-08-26 13:43