1. 設計模式之策略模式

        共 3392字,需瀏覽 7分鐘

         ·

        2021-03-29 10:34

        作者 | 湯姆大叔


        介紹

        策略模式定義了算法家族,分別封裝起來,讓他們之間可以互相替換,此模式讓算法的變化不會影響到使用算法的客戶。

        正文

        在理解策略模式之前,我們先來一個例子,一般情況下,如果我們要做數(shù)據合法性驗證,很多時候都是按照swith語句來判斷,但是這就帶來幾個問題,首先如果增加需求的話,我們還要再次修改這段代碼以增加邏輯,而且在進行單元測試的時候也會越來越復雜,代碼如下:
        validator = {    validate: function (value, type) {        switch (type) {            case 'isNonEmpty ':                {                    return true; // NonEmpty 驗證結果                }            case 'isNumber ':                {                    return true; // Number 驗證結果                    break;                }            case 'isAlphaNum ':                {                    return true; // AlphaNum 驗證結果                }            default:                {                    return true;                }        }    }};// 測試alert(validator.validate("123", "isNonEmpty"));

        那如何來避免上述代碼中的問題呢,根據策略模式,我們可以將相同的工作代碼單獨封裝成不同的類,然后通過統(tǒng)一的策略處理類來處理,OK,我們先來定義策略處理類,代碼如下:

        var validator = {
        // 所有可以的驗證規(guī)則處理類存放的地方,后面會單獨定義 types: {},
        // 驗證類型所對應的錯誤消息 messages: [],
        // 當然需要使用的驗證類型 config: {},
        // 暴露的公開驗證方法 // 傳入的參數(shù)是 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查詢是否有存在的驗證規(guī)則 checker = this.types[type]; // 獲取驗證規(guī)則的驗證類
        if (!type) { continue; // 如果驗證規(guī)則不存在,則不處理 } if (!checker) { // 如果驗證規(guī)則類不存在,拋出異常 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; }};

        然后剩下的工作,就是定義types里存放的各種驗證類了,我們這里只舉幾個例子:

        // 驗證給定的值是否不為空validator.types.isNonEmpty = {    validate: function (value) {        return value !== "";    },    instructions: "傳入的值不能為空"};
        // 驗證給定的值是否是數(shù)字validator.types.isNumber = { validate: function (value) { return !isNaN(value); }, instructions: "傳入的值只能是合法的數(shù)字,例如:1, 3.14 or 2010"};
        // 驗證給定的值是否只是字母或數(shù)字validator.types.isAlphaNum = { validate: function (value) { return !/[^a-z0-9]/i.test(value); }, instructions: "傳入的值只能保護字母和數(shù)字,不能包含特殊字符"};

        使用的時候,我們首先要定義需要驗證的數(shù)據集合,然后還需要定義每種數(shù)據需要驗證的規(guī)則類型,代碼如下:

        var data = {    first_name: "Tom",    last_name: "Xu",    age: "unknown",    username: "TomXu"};
        validator.config = { first_name: 'isNonEmpty', age: 'isNumber', username: 'isAlphaNum'};

        最后,獲取驗證結果的代碼就簡單了:

        validator.validate(data);
        if (validator.hasErrors()) { console.log(validator.messages.join("\n"));}

        總結

        策略模式定義了一系列算法,從概念上來說,所有的這些算法都是做相同的事情,只是實現(xiàn)不同,他可以以相同的方式調用所有的方法,減少了各種算法類與使用算法類之間的耦合。

        從另外一個層面上來說,單獨定義算法類,也方便了單元測試,因為可以通過自己的算法進行單獨測試。

        實踐中,不僅可以封裝算法,也可以用來封裝幾乎任何類型的規(guī)則,是要在分析過程中需要在不同時間應用不同的業(yè)務規(guī)則,就可以考慮是要策略模式來處理各種變化。

        本文完?


        推薦閱讀

        JavaScript設計模式之單例模式

        JavaScript設計模式之構造函數(shù)模式

        設計模式之建造者模式

        設計模式之工廠模式

        設計模式之裝飾者模式

        設計模式之外觀模式

        設計模式之代理模式

        設計模式之觀察者模式


        學習更多技能

        請點擊下方web前端開發(fā)


        瀏覽 22
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
          
          

            1. 美女脱个精光露出小网站 | 久久网逼 | 欧美丁香五月 | 做爱网站现在观看 | 一区不卡在线观看 |