成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

前端也要學(xué)系列:設(shè)計模式之策略模式

Anchorer / 642人閱讀

摘要:做前端開發(fā)已經(jīng)好幾年了,對設(shè)計模式一直沒有深入學(xué)習(xí)總結(jié)過。今天第一天,首先來講策略模式。什么是策略模式四兄弟的經(jīng)典設(shè)計模式中,對策略模式的定義如下定義一系列的算法,把它們一個個封裝起來,并且使它們可互相替換。

做前端開發(fā)已經(jīng)好幾年了,對設(shè)計模式一直沒有深入學(xué)習(xí)總結(jié)過。隨著架構(gòu)相關(guān)的工作越來越多,越來越能感覺到設(shè)計模式成為了我前進道路上的一個阻礙。所以從今天開始深入學(xué)習(xí)和總結(jié)經(jīng)典的設(shè)計模式以及面向?qū)ο蟮膸状笤瓌t。

今天第一天,首先來講策略模式。

什么是策略模式?

GoF四兄弟的經(jīng)典《設(shè)計模式》中,對策略模式的定義如下:

定義一系列的算法,把它們一個個封裝起來,并且使它們可互相替換。

上邊這句話,從字面來看很簡單。但是如何在開發(fā)過程中去應(yīng)用,僅憑一個定義依然是一頭霧水。以筆者曾經(jīng)做過的商戶進銷存系統(tǒng)為例:

某超市準(zhǔn)備舉行促銷活動,市場人員經(jīng)過調(diào)查分析制定了一些促銷策略:

購物滿100減10

購物滿200減30

購物滿300減50

。。。

收銀軟件的界面是這樣的(簡單示意):

我們應(yīng)該如何計算實際消費金額?

最初的實現(xiàn)是這樣的:

//方便起見,我們把各個促銷策略定義為枚舉值:0,1,2...
var getActualTotal = function(onSaleType,originTotal){
    if(onSaleType===0){
        return originTotal-Math.floor(originTotal/100)*10
    }
    if(onSaleType===1){
        return originTotal-Math.floor(originTotal/200)*30
    }
    if(onSaleType===0){
        return originTotal-Math.floor(originTotal/300)*50
    }
}

getActualTotal(1,2680); //2208

上面這段代碼很簡單,而且缺點也很明顯。隨著我的滿減策略逐漸增多,getActualTotal函數(shù)會越變越大,而且充滿了if判斷,稍一疏忽就容易弄錯。

OK,有人說我很懶,雖然這樣不夠優(yōu)雅但并不影響我的使用,畢竟?jié)M減策略再多也多不到哪去。
我只能說,需求永遠(yuǎn)不是程序員定的。。這時,市場人員說我們新版程序添加了會員功能,我們需要支持以下的促銷策略:

會員促銷策略:

會員充300返60,且首單打9折

會員充500返100,且首單打8折

會員充1000返300,且首單打7折

...

這個時候,如果你還在原先的getActualTotal函數(shù)中繼續(xù)添加if判斷,我想如果你的領(lǐng)導(dǎo)review你這段代碼,可能會懷疑自己當(dāng)初怎么把你招進來。。

OK,我們終于下定決心要重構(gòu)促銷策略的代碼,我們可以這么做:

var vipPolicy_0=function(originTotal){
    return originTotal-Math.floor(originTotal/100)*10
}
var vipPolicy_1=function(originTotal){
    return originTotal-Math.floor(originTotal/200)*30
}
...
//會員充1000返300
var vipPolicy_10=function(account,originTotal){
    if(account===0){
        account+=1300;
        return originTotal*0.9
    }else{
        account+=1300;
        return originTotal;
    }
    return originTotal-Math.floor(originTotal/200)*30
}
...
var vipPolicy_n=function(){
    ...
}

var getActualTotal=function(onSaleType,originTotal,account){
    switch(onSaleType){
        case 0:
            return vipPolicy_0(originTotal);
        case 1:
            return vipPolicy_0(originTotal);
        ...
        case n:
            return ...
        default:
            return originTotal;
    }
}

好了,現(xiàn)在我們每種策略都有自己獨立的空間了,看起來井井有條。但是還有兩個問題沒有解決:

隨著促銷策略的增加,getActualTotal的代碼量依然會越來越大

系統(tǒng)缺乏彈性,如果需要增加一種策略,那么除了添加一個策略函數(shù),還需要修改switch...case..語句

讓我們再來回顧一下策略模式的定義:

定義一系列的算法,把它們一個個封裝起來,并且使它們可互相替換

在我們的例子中,每種促銷策略的實現(xiàn)方式是不一樣的,但我們最終的目的都是為了求得實際金額。策略模式可以把我們對促銷策略的算法一個個封裝起來,并且使它們可互相替換而不影響我們對實際金額的求值,這正好是我們所需要的。

下面我們用策略模式來重構(gòu)上面的代碼:

var policies={
    "Type_0":function(originTotal){
        return originTotal-Math.floor(originTotal/100)*10 
    },
    "Type_1":function(originTotal){
        return originTotal-Math.floor(originTotal/200)*30 
    },
    ...
    "Type_n":function(originTotal){
        ... 
    }
}

var getActualTotal=function(onSaleType,originTotal,account){
    return policies["Type_"+onSaleType](originTotal,account)
}
//執(zhí)行
getActualTotal(0,2680.00);//2208

分析上面的代碼我們發(fā)現(xiàn),不管促銷策略如何增加,getActualTotal函數(shù)完全不需要再變化了。我們要做的,就是增加新策略的函數(shù)而已。

通過策略模式的代碼,我們消除了讓人反胃的大片條件分支語句,getActualTotal本身并沒有計算能力,而是將計算全權(quán)委托給了策略函數(shù)。

由此我們可以總結(jié)出策略模式實現(xiàn)的要點:

將變化的算法封裝成獨立的策略函數(shù),并負(fù)責(zé)具體的計算

委托函數(shù),該函數(shù)接受客戶請求,并將請求委托給某一個具體的策略函數(shù)

用一張UML圖表示如下:

怎么樣?現(xiàn)在看到上面這張圖是不是有了了然于胸的感覺?那就趕緊去試一試策略模式吧!

參考書籍:

《設(shè)計模式:可復(fù)用面向?qū)ο筌浖幕A(chǔ)》

《大話設(shè)計模式》

《Javascript設(shè)計模式與開發(fā)實踐》

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/95219.html

相關(guān)文章

  • 前端要學(xué)系列設(shè)計模式裝飾者模式

    摘要:什么是裝飾者模式今天我們來講另外一個非常實用的設(shè)計模式裝飾者模式。就增加功能來說,裝飾者模式相比生成子類更為靈活。下面,裝飾者模式就要正式登場了。下一步,我們可以愉快的去使用裝飾者模式啦 什么是裝飾者模式 今天我們來講另外一個非常實用的設(shè)計模式:裝飾者模式。這個名字聽上去有些莫名其妙,不著急,我們先來記住它的一個別名:包裝器模式。 我們記著這兩個名字來開始今天的文章。 首先還是上《設(shè)計...

    高勝山 評論0 收藏0
  • 正則表達(dá)式

    摘要:本文內(nèi)容共正則表達(dá)式火拼系列正則表達(dá)式回溯法原理學(xué)習(xí)正則表達(dá)式,是需要懂點兒匹配原理的。正則表達(dá)式迷你書問世了讓幫你生成和解析參數(shù)字符串最全正則表達(dá)式總結(jié)驗證號手機號中文郵編身份證地址等是正則表達(dá)式的縮寫,作用是對字符串執(zhí)行模式匹配。 JS 的正則表達(dá)式 正則表達(dá)式 一種幾乎可以在所有的程序設(shè)計語言里和所有的計算機平臺上使用的文字處理工具。它可以用來查找特定的信息(搜索),也可以用來查...

    bang590 評論0 收藏0
  • 前端要學(xué)Docker??!

    摘要:表示創(chuàng)建了一個,這是一條虛線,虛線從開始到結(jié)束指向了中間的框里。具體安裝參考官網(wǎng)文檔下載完成后打開終端運行成功運行則表示安裝成功了。 Docker這兩年非?;馃幔彩歉鞔髲S必用的好東西,這兩天沒事玩了一下感覺很不錯,學(xué)起來也不難 寫下此文共勉學(xué)習(xí)。 關(guān)于Docker Docker 可理解為跑在宿主機上的非常精簡、小巧、高度濃縮的虛擬機。 它可以將容器里的進程安穩(wěn)的在宿主機上運行。 Do...

    Tikitoo 評論0 收藏0
  • 論一個前端工程師如何快速學(xué)習(xí),成長。準(zhǔn)備自己的35歲 【-原創(chuàng)精讀】

    showImg(https://segmentfault.com/img/bVbw3tK?w=1240&h=827); 前端工程師這個崗位,真的是反人性的 我們來思考一個問題: 一個6年左右經(jīng)驗的前端工程師: 前面兩年在用jQuery 期間一直在用React-native(一步一步踩坑過來的那種) 最近兩年還在寫微信小程序 下面一個2年經(jīng)驗的前端工程師: 并不會跨平臺技術(shù),他的兩年工作都是Reac...

    RdouTyping 評論0 收藏0

發(fā)表評論

0條評論

Anchorer

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<