這篇文章主要介紹了深入理解JavaScript系列(33):設計模式之策略模式詳解,策略模式定義了算法家族,分別封裝起來,讓他們之間可以互相替換,此模式讓算法的變化不會影響到使用算法的客戶,需要的朋友可以參考下
介紹
策略模式定義了算法家族,分別封裝起來,讓他們之間可以互相替換,此模式讓算法的變化不會影響到使用算法的客戶。
正文
在理解策略模式之前,我們先來一個例子,一般情況下,如果我們要做數據合法性驗證,很多時候都是按照swith語句來判斷,但是這就帶來幾個問題,首先如果增加需求的話,我們還要再次修改這段代碼以增加邏輯,而且在進行單元測試的時候也會越來越復雜,代碼如下:
代碼如下:
// 所有可以的驗證規則處理類存放的地方,後面會單獨定義
types: {},
// 驗證類型所對應的錯誤消息
messages: [],
// 當然需要使用的驗證類型
config: {},
// 暴露的公開驗證方法
// 傳入的參數是 key => value對
validate: function (data) {
var i, msg, type, checker, result_ok;
// 清空所有的錯誤信息
this.messages = [];
for (i in data) {
if (data.hasOwnProperty(i)) {
type = this.config[i]; // 根據key查詢是否有存在的驗證規則
checker = this.types[type]; // 獲取驗證規則的驗證類
if (!type) {
continue; // 如果驗證規則不存在,則不處理
}
if (!checker) { // 如果驗證規則類不存在,拋出異常
throw {
name: "ValidationError",
message: "No handler to validate type " + type
};
}
result_ok = checker.validate(data[i]); // 使用查到到的單個驗證類進行驗證
if (!result_ok) {
msg = "Invalid value for *" + i + "*, " + checker.instructions;
this.messages.push(msg);
}
}
}
return this.hasErrors();
},
// helper
hasErrors: function () {
return this.messages.length !== 0;
}
};
// 驗證給定的值是否是數字
validator.types.isNumber = {
validate: function (value) {
return !isNaN(value);
},
instructions: "傳入的值只能是合法的數字,例如:1, 3.14 or 2010"
};
// 驗證給定的值是否只是字母或數字
validator.types.isAlphaNum = {
validate: function (value) {
return !/[^a-z0-9]/i.test(value);
},
instructions: "傳入的值只能保護字母和數字,不能包含特殊字符"
};
validator.config = {
first_name: 'isNonEmpty',
age: 'isNumber',
username: 'isAlphaNum'
};
if (validator.hasErrors()) { +
console.log(validator.messages.join("n"));
}
策略模式定義了一系列算法,從概念上來說,所有的這些算法都是做相同的事情,只是實現不同,他可以以相同的方式調用所有的方法,減少了各種算法類與使用算法類之間的耦合。
從另外一個層面上來說,單獨定義算法類,也方便了單元測試,因為可以通過自己的算法進行單獨測試。
實踐中,不僅可以封裝算法,也可以用來封裝幾乎任何類型的規則,是要在分析過程中需要在不同時間應用不同的業務規則,就可以考慮是要策略模式來處理各種變化。