JavaScript設計模式三(策略模式)

JavaScript設計模式三(策略模式)

策略模式定義

定義一系列算法,把他們一個個封裝起來吨拗,并且使他們相互替換

我們可以先看一個例子

策略模式計算年終獎

大家知道年終獎的發(fā)放是和工資基數和年終考評來計算的算柳,例如A是4個月工資媒役,B是3個月工資偿曙,C是2個月工資龙亲。

1、最初的代碼實現

var calculateBonus = function(level, salary) {
    if (level === 'A') {
        return salary*4;
    }
    
    if (level === 'B') {
        return salary*3;
    }
    
    if (level === 'C') {
        return salary*2;
    }
}

使用方法:
calcaluteBonus('B', 10000)

這段代碼平常我們見到的很多恳不,但是它有著明顯的缺點

  • 函數很雜,隨著業(yè)務邏輯的增加开呐,這個函數會越來越大
  • 缺乏彈性烟勋,例如我們A的考評變成5倍,或者增加D的考評筐付,必須要去修改這個函數卵惦,這里是違反了開發(fā)-封閉原則
  • 算法不存在復用性,例如我們需要再另外一個函數中使用這些算法瓦戚,需要重新再寫一遍

2沮尿、利用組合函數重構代碼

簡單來解釋,就是把那些算法封裝到一個個函數里面。


var algorithmA = function(salary) {
    return salary*4;
}

var algorithmB = function(salary) {
    return salary*3;
}

var algorithmC = funtion(salary) {
    return salary*2;
}

var calculateBonus = function(level, salary) {
    if (level === 'A') {
        return algorithmA(salary);
    }
    
    if (level === 'B') {
        return algorithmB(salary*3);
    }
    
    if (level === 'C') {
        return algorithmC(salary*2);
    }
}

這么修改之后畜疾,這些算法我們可以在其他函數里面復用了赴邻,但是還是沒有解決calculateBonus函數龐大的問題。

3啡捶、使用策略模式重構代碼

一個策略模式的程序至少由兩部分組成

  • 一組策略類姥敛,也就是算法,這些策略類會封裝算法瞎暑,并且負責具體的計算規(guī)則
  • 環(huán)境上下文彤敛,接受客戶的請求,然后把請求委托給某一個策略類了赌。因此在這個上下文中要維持對某一個策略對象的引用墨榄。

我們先看一個模仿面向對象語言的實現:

// 策略類
var algorithmA = function(){}

algorithmA.prototype.calculate = function(salary) {
    return salary*4;
}

var algorithmB = function(){}

algorithmB.prototype.calculate = function(salary) {
    return salary*3;
}

var algorithmB = function(){}

algorithmB.prototype.calculate = function(salary) {
    return salary*2;
}

// 環(huán)境上下文

var 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() {
    return this.strategy.calculate( this.salary );
}

// 使用

var bonus = new Bonus();

bonus.setSalary(10000);
bonus.setStrategy(new algorithmA());

console.log(bonus.getBonus());

剛才上面說到了面向對象的的實現,但是其實我們很少會這樣寫勿她,我們看看JavaScript的版本

4渠概、JavaScript版本的策略模式

var strategies = {
    "A": function(salary) {
        return salary*4;
    },
    "B": function(salary) {
        return salary*3;
    },
    "C": function(salary) {
        return salary*2;
    },
};

var calculateBonus = function(level, salary) {
    return strategies[level](salary);
};

calculateBonus('A', 10000);

驚不驚喜,意不意外嫂拴,就是這么簡單播揪。

策略模式更加廣義的用法

上面我們說的策略模式封裝的是算法,但是實際上我們不僅僅可以封裝算法筒狠,還可以封裝一些業(yè)務規(guī)則猪狈,例如表單驗證里面,我們可以封裝不同的校驗邏輯辩恼,這里就不舉例說明了雇庙,如果有興趣可以參考JavaScript設計模式與實踐這本書

策略模式的優(yōu)缺點

優(yōu)點:

  • 策略模式利用組合、委托和多態(tài)的技術和思想灶伊,能夠有效的避免多重條件選擇語句
  • 策略模式符合開發(fā)-封閉原則疆前,把算法封裝在獨立的strategy中,讓算法利于切換聘萨、理解和擴展
  • 策略模式的算法能夠很方便的在其他地方復用
  • 策略模式利用組合和委托讓環(huán)境上下文有執(zhí)行算法的能力竹椒,這也是繼承的一種體現

缺點:

  • 策略模式需要在代碼中增加許多策略類或者策略對象
  • 要使用好策略模式的前提是:必須了解所有的strategy,并且知道他們之間的不同點米辐,這是違反最少知識原則的胸完。
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市翘贮,隨后出現的幾起案子赊窥,更是在濱河造成了極大的恐慌,老刑警劉巖狸页,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锨能,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機址遇,發(fā)現死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門熄阻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人傲隶,你說我怎么就攤上這事饺律。” “怎么了跺株?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵复濒,是天一觀的道長。 經常有香客問我乒省,道長巧颈,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任袖扛,我火速辦了婚禮砸泛,結果婚禮上,老公的妹妹穿的比我還像新娘蛆封。我一直安慰自己唇礁,他們只是感情好,可當我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布惨篱。 她就那樣靜靜地躺著盏筐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪砸讳。 梳的紋絲不亂的頭發(fā)上琢融,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天,我揣著相機與錄音簿寂,去河邊找鬼漾抬。 笑死,一個胖子當著我的面吹牛常遂,可吹牛的內容都是我干的纳令。 我是一名探鬼主播,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼烈钞,長吁一口氣:“原來是場噩夢啊……” “哼泊碑!你這毒婦竟也來了?” 一聲冷哼從身側響起毯欣,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎臭脓,沒想到半個月后酗钞,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年砚作,在試婚紗的時候發(fā)現自己被綠了窘奏。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡葫录,死狀恐怖着裹,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情米同,我是刑警寧澤骇扇,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站面粮,受9級特大地震影響少孝,放射性物質發(fā)生泄漏。R本人自食惡果不足惜熬苍,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一稍走、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧柴底,春花似錦婿脸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至凿歼,卻和暖如春褪迟,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背答憔。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工味赃, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人虐拓。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓心俗,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蓉驹。 傳聞我的和親對象是個殘疾皇子城榛,可洞房花燭夜當晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內容

  • 工廠模式類似于現實生活中的工廠可以產生大量相似的商品,去做同樣的事情态兴,實現同樣的效果;這時候需要使用工廠模式狠持。簡單...
    舟漁行舟閱讀 7,767評論 2 17
  • 工廠模式 單體模式 模塊模式 代理模式 職責鏈模式 命令模式 模板方法模式 策略模式 發(fā)布-訂閱模式 中介者模式 ...
    HelloJames閱讀 1,008評論 0 6
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,164評論 25 707
  • 在銷售過程中,我們通常會遇到什么問題瞻润?下面就是采訪美女銷售高手的經驗總結喘垂。 客戶跟我們玩命的砍價甜刻,或者告訴我們沒有...
    我是醬職閱讀 720評論 0 0
  • 微服務架構(microservices architecture)是服務導向架構(service-oriented...
    劉林三閱讀 675評論 0 0