標籤:另一個 需要 if語句 參數 覆蓋 調用 分離 應該 理解
策略模式:定義一系列的演算法,把它們一個個封裝起來,並且使它們可以相互替換。
我的理解就是把各種方法封裝成函數,同時存在一個可以調用這些方法的公用函數。這樣做的好處是可以消化掉內部的分支判斷,使代碼效率更高。
使用原則模式計算獎金
現在要實現這樣一個東西,年終獎是根據員工的工資基數和年底績效情況來發放的。例如,績效為S的人年終獎有4倍工資,績效為A的人年終獎有3倍工資,而績效為B的人年終獎是2倍工資。假設財務部要求我們提供一段代碼,來方便他們計算員工的年終獎。
思路一:建立一個函數,接收兩個參數,一個是績效,一個是工資底數,然後返回年終獎
1 var calculate = function( level, salary ){ //建立了一個計算函數 2 if ( level === ‘S‘ ){ 3 return salary * 4; 4 } 5 if ( level === ‘A‘ ){ 6 return salary * 3; 7 } 8 if ( level === ‘B‘ ){ 9 return salary * 2;10 }11 };12 calculate( ‘B‘, 20000 ); // 輸出:4000013 calculate( ‘S‘, 6000 ); // 輸出:24000
這段代碼的缺點很多
(1)calculate函數比較龐大,包含了很多if語句,這些語句需要覆蓋所有的邏輯分支
(2)函數缺乏彈性,如果增加了一種新的績效等級C,或者想把績效S的獎金係數改為5,那我們必須深入calculate函數的內部實現,這是違反開放-封閉原則的。
思路二:用組合函數完成,一個函數用來計算相應獎金,另一個函數用來判斷調用哪個計算函數
1 var levelS = function( salary ){ 2 return salary * 4; 3 }; 4 var levelA = function( salary ){ 5 return salary * 3; 6 }; 7 var levelB = function( salary ){ 8 return salary * 2; 9 };10 11 var calculate = function( level, salary ){12 if ( level === ‘S‘ ){13 return levelS( salary );14 }15 if ( level === ‘A‘ ){16 return levelA( salary );17 }18 if ( level === ‘B‘ ){19 return levelB( salary );20 }21 };22 23 calculate( ‘A‘ , 10000 ); // 輸出:30000
這段代碼比上面的好一些,但是還是沒解決關鍵問題,calculate函數有可能變得越來越大,而且函數依舊缺乏彈性。
思路三:策略模式,將不變的部分和變化的部分隔開是每個設計模式的主題,策略模式也不例外,策略模式的目的就是將演算法的使用與演算法的實現分離開來。
策略模式就是分成策略函數和調用函數,調用函數不應該包含分支判斷,調用任何策略函數的方式應該是一致的:
1 var S=function( salary ){ 2 return salary * 4; 3 }; 4 5 var A=function( salary ){ 6 return salary * 3; 7 }; 8 9 var B=function( salary ){10 return salary * 2;11 }12 13 var calculate = function( func, salary ){ //高階函數14 return func( salary );15 };16 17 calculate( S, 20000 ); // 輸出:8000018 calculate( A, 10000 ); // 輸出:30000
或者使用對象,讓策略彼此間可以產生聯絡:
1 var Lv = { 2 "S": function( salary ){ 3 return salary * 4; 4 }, 5 "A": function( salary ){ 6 return salary * 3; 7 }, 8 "B": function( salary ){ 9 return salary * 2;10 }11 };12 13 var calculate = function( level, salary ){ 14 return Lv[ level ]( salary ); //這裡明確只能使用Lv對象的方法,讓calulate的職能更清晰,上面calulate太過通用15 };16 17 calculate( ‘S‘, 20000 ); // 輸出:8000018 calculate( ‘A‘, 10000 ); // 輸出:30000總結
策略模式的優點:
策略模式利用組合、委託和多態等技術和思想,可以有效地避免多重條件選擇語句。
策略模式提供了對開放—封閉原則的完美支援,將演算法封裝在獨立的strategy中,使得它們易於切換,易於理解,易於擴充。
總結一下就是將策略函數封裝,調用函數的實質就是調用這些策略函數。
javascript設計模式與開發實踐閱讀筆記(5)——策略模式