這次帶給大家設計模式的策略模式怎樣在前端使用,設計模式的策略模式在前端使用注意事項有哪些,下面就是實戰案例,一起來看看。
GoF四兄弟的經典《設計模式》中,對策略模式的定義如下:
定義一系列的演算法,把它們一個個封裝起來,並且使它們可互相替換。
上邊這句話,從字面來看很簡單。但是如何在開發過程中應用,僅憑一個定義依然是一頭霧水。以筆者曾經做過的商家進銷存系統為例:
某家超市準備舉辦促銷活動,市場人員經過調查分析制定了一些促銷策略:
購物滿100減10
購物滿200減30
購物滿300減50
收銀軟體的介面是這樣的(簡單示意):
我們該如何計算實際消費金額?
最初的實作是這樣的:<pre class="brush:php;toolbar:false">//方便起见,我们把各个促销策略定义为枚举值: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</pre>
上面這段程式碼很簡單,而且缺點也很明顯。隨著我的滿減策略逐漸增多,getActualTotal
函數會越變越大,而且充滿了
判斷,稍一疏忽就容易弄錯。
我只能說,需求永遠不是程式設計師定的。 。這時,市場人員說我們新版程式加入了會員功能,我們需要支援以下的促銷策略:
這個時候,如果你還在原先的
getActualTotal
函數中繼續加上
判斷,我想如果你的領導者review你這段程式碼,可能會懷疑自己當初怎麼把你招進來。 。
OK,我們終於下定決心要重構促銷策略的程式碼,我們可以這麼做:
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; } }
隨著促銷策略的增加,
#系統缺乏彈性,如果需要增加一種策略,那麼除了加入一個策略函數,還需要修改
讓我們再來回顧一下策略模式的定義:
定義一系列的演算法,把它們一個個封裝起來,並且使它們可互相替換
在我們的例子中,每種促銷策略的實現方式是不一樣的,但我們最終的目的都是為了求實際金額。策略模式可以把我們對促銷策略的演算法一個個封裝起來,並且使它們可互相替換而不影響我們對實際金額的求值,這正好是我們所需要的。
下面我們用策略模式來重構上面的程式碼:<pre class="brush:php;toolbar:false">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)
}
//执行
getActualTotal(0,2680.00);//2208</pre>
分析上面的程式碼我們發現,不管促銷策略如何增加,
函數完全不需要再變化了。我們要做的,就是增加新策略的函數而已。 透過策略模式的程式碼,我們消除了讓人反胃的大片條件分支語句,
本身並沒有計算能力,而是將計算全權委託給了策略函數。
委託函數,函數接受客戶請求,並將請求委託給某一個具體的策略函數
以UML圖表示如下:
怎麼樣?現在看到上面這張圖是不是有了然於胸部的感覺?那就趕快去試試策略模式吧!
參考書籍:
《設計模式:可重複使用物件導向軟體的基礎》
《大話設計模式》
#《Javascript設計模式與開發實踐》
做前端開發已經好幾年了,對設計模式一直沒有深入學習總結過。隨著架構相關的工作越來越多,越來越能感覺到設計模式成為了我前進道路上的阻礙。所以從今天開始深入學習和總結經典的設計模式以及物件導向的幾大原則。
今天第一天,首先來講策略模式。
GoF四兄弟的經典《設計模式》中,對策略模式的定義如下:
定義一系列的演算法,把它們一個個封裝起來,並且使它們可互相替換。
上邊這句話,從字面來看很簡單。但是如何在開發過程中應用,僅憑一個定義依然是一頭霧水。以筆者曾經做過的商家進銷存系統為例:
某家超市準備舉辦促銷活動,市場人員經過調查分析制定了一些促銷策略:
購物滿100減10
購物滿200減30
購物滿300減50
收銀軟體的介面是這樣的(簡單示意):
我們該如何計算實際消費金額?
最初的實作是這樣的:<pre class="brush:php;toolbar:false">//方便起见,我们把各个促销策略定义为枚举值: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</pre>
上面這段程式碼很簡單,而且缺點也很明顯。隨著我的滿減策略逐漸增多,getActualTotal
函數會越變越大,而且充滿了
判斷,稍一疏忽就容易弄錯。
我只能說,需求永遠不是程式設計師定的。 。這時,市場人員說我們新版程式加入了會員功能,我們需要支援以下的促銷策略:
這個時候,如果你還在原先的
getActualTotal
函數中繼續加上
判斷,我想如果你的領導者review你這段程式碼,可能會懷疑自己當初怎麼把你招進來。 。
OK,我們終於下定決心要重構促銷策略的程式碼,我們可以這麼做:
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; } }
隨著促銷策略的增加,
#系統缺乏彈性,如果需要增加一種策略,那麼除了加入一個策略函數,還需要修改
定义一系列的算法,把它们一个个封装起来,并且使它们可互相替换
在我们的例子中,每种促销策略的实现方式是不一样的,但我们最终的目的都是为了求得实际金额。策略模式可以把我们对促销策略的算法一个个封装起来,并且使它们可互相替换而不影响我们对实际金额的求值,这正好是我们所需要的。
下面我们用策略模式来重构上面的代码:
<pre class="brush:php;toolbar:false">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) } //执行 getActualTotal(0,2680.00);//2208</pre>分析上面的代码我们发现,不管促销策略如何增加,getActualTotal
函数完全不需要再变化了。我们要做的,就是增加新策略的函数而已。
通过策略模式的代码,我们消除了让人反胃的大片条件分支语句,getActualTotal
本身并没有计算能力,而是将计算全权委托给了策略函数。
由此我们可以总结出策略模式实现的要点:
将变化的算法封装成独立的策略函数,并负责具体的计算
委托函数,该函数接受客户请求,并将请求委托给某一个具体的策略函数
用一张UML图表示如下:
怎么样?现在看到上面这张图是不是有了了然于胸的感觉?那就赶紧去试一试策略模式吧!
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
以上是設計模式的策略模式如何在前端使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!