<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          設(shè)計模式之策略模式

          共 3392字,需瀏覽 7分鐘

           ·

          2021-03-29 10:34

          作者 | 湯姆大叔


          介紹

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

          正文

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

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

          var validator = {
          // 所有可以的驗證規(guī)則處理類存放的地方,后面會單獨定義 types: {},
          // 驗證類型所對應(yīng)的錯誤消息 messages: [],
          // 當(dāng)然需要使用的驗證類型 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]; // 根據(jù)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]); // 使用查到到的單個驗證類進(jìn)行驗證 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: "傳入的值只能保護(hù)字母和數(shù)字,不能包含特殊字符"};

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

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

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

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

          總結(jié)

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

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

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

          本文完?


          推薦閱讀

          JavaScript設(shè)計模式之單例模式

          JavaScript設(shè)計模式之構(gòu)造函數(shù)模式

          設(shè)計模式之建造者模式

          設(shè)計模式之工廠模式

          設(shè)計模式之裝飾者模式

          設(shè)計模式之外觀模式

          設(shè)計模式之代理模式

          設(shè)計模式之觀察者模式


          學(xué)習(xí)更多技能

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


          瀏覽 22
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  8050午夜网 | 91五月婷婷华人网站 | 日韩人妻视频 | 一区二区三区四区视频在线 | 欧美插穴网|