策略模式
定義:定義一系列算法,把它們一個個封裝起來,并且可以互相替換
例如,我們要計算年終獎,年終獎根據績效 A、B、C 來計算最終數值
實現
最初我們很容易想到用 分支 if 來解決這個問題,如果績效 = A 則工資 x 2,如果績效 = B 則工資 x 3
如果經常使用這樣的分支結構,你會發(fā)現代碼耦合度很高,很容易就出現一大坨代碼堆砌在一起,只是 x 2 或者 x 3 不足以形成難以維護的結構,但如果不是 x 2 而是一個復雜的代碼塊,我們顯然會想到封裝里面的代碼!
var performA = function (salary) {
return salary * 4;
};
var performB = function (salary) {
return salary * 3;
};
var performC = function (salary) {
return salary * 2;
};
var calcBonus = function (level, salary) {
if (level == "A") {
return performA(salary);
} else if (level == "B") {
return performB(salary);
} else if (level == "C") {
return performC(salary);
}
};
是的,雖然我們優(yōu)化了代碼,但沒好到哪去,如果要添加一個 D 級,我們還是得堆砌代碼
讓我們來看看策略模式怎么做吧,策略模式讓 策略 被定義和封裝,且可以相互替換
這就是最終代碼了,但在 javascript 中實現策略相較 C# 或者其他語言來說要容易的多,在下面舉例了 C# 代碼
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);
};
需要注意的是 strategies 對象存儲的 3 個匿名函數, Func 類是用來存儲函數的,需要一定的函數工具類基礎
掌握這樣的思想以后,試著把 {"A", (salary) => salary * 4}
解耦出去動態(tài)添加即可~
using System;
using System.Collections.Generic;
public class Program
{
private static Dictionary<string, Func<double, double>> strategies = new Dictionary<string, Func<double, double>>()
{
{"A", (salary) => salary * 4},
{"B", (salary) => salary * 3},
{"C", (salary) => salary * 2}
};
private static double CalculateBonus(string level, double salary)
{
return strategies[level](salary);
}
public static void Main(string[] args)
{
string level = "A";
double salary = 1000;
double bonus = CalculateBonus(level, salary);
Console.WriteLine("Bonus: " + bonus);
}
}
思想
通過上面的重構:
- 消除了大片的分支語句
- 計算獎金的邏輯不再存儲在 CalculateBonus 里了,而是分布在策略對象里
- 策略對象只負責計算獎金
- 策略對象之間可以相互替換
實戰(zhàn) - 表單
這是一種尤為常見的表單驗證方式,相信絕大多數前端程序員這樣寫過
顯然能發(fā)現,這里的 if 堆砌過多,不僅如此,內部的 邏輯 相比上面的代碼也更復雜文章來源:http://www.zghlxwxcb.cn/news/detail-732574.html
var registerForm = function (form) {
if (form.username.value === "") {
alert("用戶名不能為空");
return false;
}
if (form.password.value.length < 6) {
alert("密碼長度不能少于6位");
return false;
}
if (!/(^1[3|5|8][0-9]{9}$)/.test(form.phoneNumber.value)) {
alert("手機號碼格式不正確");
return false;
}
};
我們可以用策略模式的思路來實現類似這樣的代碼,這樣當我們需要增加驗證步驟時,只需要添加策略內容即可:文章來源地址http://www.zghlxwxcb.cn/news/detail-732574.html
var validateStrategy = {
isNotEmpty: function (form) {
if (form.name === "") {
return "用戶名不能為空";
}
return "";
},
minLength: function (form) {
if (form.password.length < 6) {
return "密碼長度不能少于6位";
}
return "";
},
isMobile: function (form) {
if (!/(^1[3|5|8][0-9]{9}$)/.test(form.phone)) {
return "手機號碼格式不正確";
}
return "";
},
};
var validate = function (form) {
for (let func in validateStrategy) {
if (
validateStrategy.hasOwnProperty(func) &&
typeof validateStrategy[func] === "function"
) {
var msg = validateStrategy[func](form);
if (msg != "") return false;
}
}
return true;
};
到了這里,關于策略模式,一種廣泛應用于各種情況的設計模式(設計模式與開發(fā)實踐 P5)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!