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

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

在Java框架中,設計模式和架構模式的區別在於:設計模式定義了在軟體設計中解決常見問題的抽象解決方案,專注於類別和物件之間的交互,例如工廠模式。架構模式定義了系統結構和模組之間的關係,關注系統元件的組織和交互,如分層架構。

裝飾器模式是一種結構型設計模式,允許動態添加物件功能,無需修改原始類別。它透過抽象組件、具體組件、抽象裝飾器和具體裝飾器的協作實現,可以靈活擴展類別功能,滿足變化的需求。範例中,將牛奶和摩卡裝飾器添加到Espresso,總價為2.29美元,展示了裝飾器模式在動態修改物件行為方面的強大功能。

設計模式透過提供可重複使用和可擴展的解決方案來解決程式碼維護難題:觀察者模式:允許物件訂閱事件,並在事件發生時收到通知。工廠模式:提供了一種創建物件的集中式方式,而無需依賴特定類別。單例模式:確保一個類別只有一個實例,用於建立全域可存取的物件。

TDD用於編寫高品質PHP程式碼,步驟包括:編寫測試案例,描述預期功能並使其失敗。編寫程式碼,僅使測試案例通過,無需過度優化或詳細設計。測試案例通過後,優化和重構程式碼以提高可讀性、可維護性和可擴展性。

適配器模式是一種結構型設計模式,允許不相容物件協同工作,它將一個介面轉換為另一個,使物件能夠順利互動。物件適配器透過建立包含被適配器對象的適配器對象,並實現目標接口,實現適配器模式。在一個實戰案例中,透過適配器模式,客戶端(如MediaPlayer)可以播放高級格式的媒體(如VLC),儘管本身僅支援普通媒體格式(如MP3)。

Guice框架應用了多項設計模式,包括:單例模式:透過@Singleton註解確保類別只有一個實例。工廠方法模式:透過@Provides註解建立工廠方法,在依賴注入時取得物件實例。策略模式:將演算法封裝成不同策略類,透過@Named註解指定具體策略。

Java框架中使用設計模式的優點包括:程式碼可讀性、可維護性和可擴充性增強。缺點包括:過度使用導致複雜性、效能開銷以及學習曲線陡峭。實戰案例:代理模式用於延遲載入物件。明智地使用設計模式可充分利用其優勢並最小化缺點。

SpringMVC框架使用以下設計模式:1.單例模式:管理Spring容器;2.門面模式:協調控制器、視圖和模型互動;3.策略模式:根據請求選擇請求處理程序;4.觀察者模式:發布和監聽應用程式事件。這些設計模式增強了SpringMVC的功能和靈活性,使開發者可以創建高效、可維護的應用程式。
