學習設計模式——策略模式,使用策略模式優化校驗表單

使用策略模式校驗表單

還在使用if else 校驗表單?每次增加字段都要加 if,編碼體驗實在太差,快來使用策略模式

策略模式的主要思路是,定義一些策略,一般存到對象裏面(策略池),然後需要使用哪種策略方法,就在需要的地方調用。
舉個例子:策略池好比一個工具箱,工具箱裏面放了一些工具(螺絲刀,扳手,錘子),需要用什麼工具就用什麼工具,想要修娃娃就用螺絲刀,修水管就用扳手,打boss就用錘子。還可以自己添加工具放入工具箱,缺把菜刀就定義一把菜刀放到工具箱,下次想打測試就可以用菜刀了。

// 對象字面量
        var strategies = {

            isNonEmpty: function(value, errorMsg) {
                if (value === '') {
                    return errorMsg;
                };
            },

            maxLength: function(value, length, errorMsg) {
                if (value.length > length) {
                    return errorMsg;
                };
            },

            isMobile: function(value, errorMsg) {
                if (!/(^1[2||3|5|7|8][0-9]{9}$)/.test(value)) {
                    return errorMsg;
                };
            },

            isSpace: function(value, errorMsg) {
                if([...value].every( item => {
                    return item === ' ';
                })) {
                    return errorMsg;
                };
            }
        };



        // 校驗表單類
        var Validator = function(strategies) {
        	if(this instanceof Validator) {
			  this.catch = [];
			  this.strategies = strategies;
			} else {
			  return new Validator(streategies);
			}
            
        };

        Object.assign(Validator.prototype, {
			addRule: function(key, fn) {
			  this.strategies[key] = fn;
			},
            add: function(dom, rules) {
              console.log("dom", dom);
                var _self = this;
                for (var i = 0, rule; rule = rules[i++]; ) {
                    (function(rule) {
                        var ary = rule.strategy.split(':');
                        _self.catch.push(function() {
                            var strategy = ary.shift();
                            ary.unshift(dom.value);
                            ary.push(rule.errorMsg);
                            return strategies && strategies[strategy] &&  strategies[strategy].apply(dom, ary);
                        });
                    })(rule);
                };
            },

            start: function() {
                for (var i = 0, validatorFunc; validatorFunc = this.catch[i++]; ) {
                    var msg = validatorFunc();
                    if (msg) {
                        return msg;
                    };
                };
            }
        });

         // 校驗方法封裝
        var validataFunc = function() {
            var validator = new Validator();

            validator.add(registerFrom.name, [{
                strategy: 'isSpace',
                errorMsg: '請輸入用戶名'
            },{ // 冒號 :分隔傳值給策略函數
                strategy: 'maxLength:10',
                errorMsg: '用戶名長度不能超過10個字符!'
            }]);
            validator.add(registerFrom.phone, [{
                strategy: 'isMobile',
                errorMsg: '手機號碼格式不正確'
            }]);
            validator.add(registerFrom.address, [{
                strategy: 'isSpace',
                errorMsg: '請輸入地址'
            }]);

            var errMsg = validator.start();
            return errMsg;
        };

    var registerFrom = $('.form-box').get(0)
    $('.submit').click(function() {
      // TODO: 數據校驗
      var errorMsg = validataFunc()
      if(errorMsg) {
        weui.topTips(errorMsg)
        return false
      }
      // 其他邏輯代碼
    }

精簡版
公司的舊angulajs1.x版本的項目表單校驗全是 if-else ,太難受了,重構

 // 校驗策略
    var strategies = {
      isNonEmpty: function(value, errorMsg) {
        if (/^\s*$/g.test(value)) {
          return errorMsg;
        }
      },
    };
    // 校驗表單類
    function Validator() {
      // 緩存
      this.catch = [];
    }
    angular.extend(Validator.prototype, {
      add: function(value, rules) {
        var _this = this;
        for (var i = 0, rule; (rule = rules[i++]); ) {
          (function(rule) {
            var arr = rule.strategy.split(':');
            _this.catch.push(function() {
              var strategy = arr.shift();
              arr.unshift(value);
              arr.push(rule.errorMsg);
              return strategies && strategis[strategy] && strategis[strategy].apply(null, arr);
            });
          })(rule);
        }
      },
      start: function() {
        for (var i = 0, validatorFunc; (validatorFunc = this.catch[i++]); ) {
          var msg = validatorFunc();
          if (msg) {
            return msg;
          }
        }
      },
    });

    // 校驗方法
    function validatorFunc() {
      var vlidator = new Validator();
      validator.add(merchantName, [{
        strategy: 'isNonEmpty',
        errorMsg: '請上傳營業執照名稱'
      }])
     
      return validator.start();
    }

    // 保存並下一步
    $scope.nextFun = function() {
      // TODO: isDebug 使用策略模式校驗,不要再寫if else了,受不鳥
      var errorMsg = validataFunc();
      if(errorMsg) {
        weui.topTips(errorMsg);
        return;
      }
  }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章