胡居仁:茍有恒夺艰,何必三更眠芋哭、五更起;最無益郁副,莫過一日曝减牺、十日寒
俗話說,條條大路通羅馬存谎,當(dāng)我們想要成功完成一件事情時拔疚,預(yù)設(shè)出多種計(jì)劃以應(yīng)對環(huán)境改變是必須的,當(dāng)真正去執(zhí)行時既荚,只需要根據(jù)當(dāng)前的環(huán)境去選擇一個提前制定好的計(jì)劃即可稚失。策略模式即是如此,用比較專業(yè)的術(shù)語定義則是:** 定義一系列的算法恰聘,把它們一個個封裝起來句各,并且使它們可以相互替換 吸占。**
一起來看一個例子吧,出自《設(shè)計(jì)模式》:
很多公司的年終獎是根據(jù)員工的工資基數(shù)和年底績效的情況來發(fā)放的凿宾。例如:績效為S的人年終獎有4倍工資矾屯,績效為A的人年終獎有3倍工資,而績效為B的人年終獎有2倍工資初厚,假設(shè)財(cái)務(wù)部要求我們提供一段代碼件蚕,來方便它們計(jì)算員工的年終獎。
我們可以不加思索的寫下如下的代碼:
var calculateBonus = function (performanceLevel, salary) {
if (performanceLevel === 'S') {
return salary * 4;
}
if (performanceLevel === 'A') {
return salary * 3;
}
if (performanceLevel === 'B') {
return salary * 2;
}
}
這段代碼十分簡單产禾,但是存在著顯而易見的缺點(diǎn):
- calculateBonus函數(shù)比較龐大排作,包含了許多 if 語句,這些語句需要覆蓋所有的邏輯分支下愈。
- calculateBonus函數(shù)缺乏彈性纽绍,如果增加一種新的績效等級C,或者想把績效S的獎金系數(shù)改為5势似,那么我們必須深入calculateBonus函數(shù)的內(nèi)部實(shí)現(xiàn),這是違反開放-封閉原則的僧著。
- 算法的復(fù)用性差履因,如果在程序的其他地方需要重用這些計(jì)算獎金的算法呢?我們的選擇只有復(fù)制和粘貼盹愚。
所以我們需要重構(gòu)這段代碼栅迄,策略模式指的是定義一系列的算法,把它們一個個封裝起來皆怕,將不變的部分和變化的部分隔開是每個設(shè)計(jì)模式的主題毅舆,策略模式也不例外,策略模式的目的就是將算法的使用和算法的實(shí)現(xiàn)分離開來愈腾,基于這個思想憋活,我們將代碼重構(gòu)如下:
var strategies = {
"S": function (salary) {
return salary * 4;
},
"A": function (salary) {
return salary * 4;
},
"B": function (salary) {
return salary * 4;
}
}
var calculateBonus = function (level, salary) {
return strategies[level](salary);
}
// 然后可以愉快的計(jì)算啦:
console.log(calculateBonus('S', 20000));
console.log(calculateBonus('A', 20000));
這樣子我們不僅可以復(fù)用算法,而且calculateBonus函數(shù)簡潔易懂虱黄。
再來看一個常見的例子:表單校驗(yàn)悦即。假設(shè)我們正在編寫一個注冊的頁面,在點(diǎn)擊注冊之前橱乱,有如下幾條校驗(yàn)邏輯:
- 用戶名不能為空
- 密碼長度不能少于6位
- 手機(jī)號碼必須符合模式
常見的代碼是這樣編寫的:
var form; //假定是從html獲取的form
form.onsubmit = function () {
if ( form.userName.value === '' ) {
return '用戶名不能為空';
}
if ( form.password.value.length < 6 ) {
return '密碼長度不能少于6位';
}
if ( !/(^1[3|5|8][0-9]{9}$)/.test(form.phoneNumber.value) ) {
return '手機(jī)號碼格式不正確';
}
}
所以學(xué)校發(fā)生了些事情辜梳,觀看了一下,耽誤了總結(jié)泳叠,明天補(bǔ)上后續(xù)作瞄。。危纫。