Design Patterns-Strategy Patterns

Keywords: Javascript Mobile less React JQuery

Focus on a Wechat Public Number: Learn React from scratch. It tells us some design patterns in a humorous way and summarizes them.

The difference between the novice and the veteran is not how many languages he knows and how many books he reads, but the clarity of his ideas and good programming habits. One thing to avoid when writing code is simple and repetitive work. The code should be revised repeatedly to improve its execution efficiency. In fact, the design pattern of type I language can't be used. In fact, you've already used the strategy pattern. jquery form validation plug-in and react form validation plug-in all use this idea. What's the advantage of this idea? Why is it more advanced than writing if else statements?

Suppose we want to implement a registration page. Before submitting the registration button, we need to do the following checking logic.
1. User name cannot be empty
2. Password length should not be less than 6 bits
3. Mobile phone numbers conform to the conventional format

page

<!DOCTYPE html>
<html>
<head lang="en">
  <meta charset="UTF-8">
  <title>Field validation</title>
</head>
<body>
  <form id="registerForm">
    enter one user name: <input type="text" name="userName" />
    Please input a password: <input type="text" name="password" />
    Please enter your cell phone number.: <input type="text" name="phoneNum" />
    <button>Submission</button>
  </form>
</body>
</html>

Looking at the big white children's shoes, it's not easy. After a few minutes, I knocked the following code.

var registerForm = document.getElementById('registerForm');
registerForm.onsubmit = function() {
  if(registerForm.userName.value === '') {
    alert('User name cannot be empty');
    return false;
  }
  if(registerForm.password.value.length < 6) {
    alert('Password length should not be less than 6 bits');
    return false;
  }
  if(!/^1[3|5|8][0-9]{9}$/.test(registerForm.phoneNum.value)) {
    alert('Incorrect format of mobile phone number');
    return false;  
  }
}

First of all, this assignment is no problem, the code can be used. A few days later, colleague Xiao Bai will also do a form verification work, borrowing the white code, but he is not happy, because the white code not only has to be copied again, but also has poor reusability. input should be defined as the same name to use. Also, if we need to change a verification rule, such as changing the password length from 6 to 6. Eight bits, but also to go deep into the internal logic of his code to modify, this time is enough to rewrite a similar.

After hearing Xiao Bai's complaint, Da Bai should turn it into a function.

function check(userName, password, phoneNum) {
  if(userName == '') {
    alert('User name cannot be empty');
    return false;
  }
  if(password.length < 6) {
    alert('Password length should not be less than 6 bits');
    return false;
  }
  if(!/^1[3|5|8][0-9]{9}$/.test(phoneNum)) {
    alert('The format of mobile phone number is incorrect');
    return false;
  }
  return true;
}

var registerForm = document.getElementById('registerForm');
var userName, password, phoneNum;
registerForm.onsubmit = function() {
  userName = registerForm.userName.value;
  password = registerForm.password.value;
  phoneNum = registerForm.phoneNum.value;
  if(!check(userName, password, phoneNum)) {
    return false;
  }
}

If there is a change in the following requirements, Xiaobai's form needs to verify more than these items, or in the verification of mobile phone number, the verification conditions of Dabai and Xiaobai are different. At this time, we need to change the function. Gradually, the function is expanding and a lot of if else judgments are made.

New ideas:
From the analysis of white code, we can see that validation of this logic needs to be separated and maintained separately. For example, length judgment, regular judgment and so on. Each validation rule can be called a validation strategy. For each specific form, we can select the validation strategy it needs and configure it flexibly.

var strategies = {
  isNonEmpty: function(error, errorMsg) {
    if(value === '') {
      return errorMsg;
    }
  },
  minLength: function(value, length, errorMsg) {
    if(value.length < length) {
      return errorMsg;
    }
  },
  isMobile: function(value, errorMsg) {
    if(!/1[3|5|8][0-9]{9}$/.test(value)) {
      return errorMsg;
    }
  }
}

Recall that jquery and bootstrap validation plug-ins should initialize a Validator object first, then call a function to bind each field to the corresponding validation strategy, and then trigger the validation process. Therefore, the object should have two functions, add() and start(), for the field binding strategy and trigger validation respectively.

function Validator() {
  this.cache = [];
}

Validator.prototype.add = function(dom, rule, errorMsg) {
  var arr = rule.split(':');
  this.cache.push(function() {
    var strategy = arr.shift();
    arr.unshift(dom.value);
    arr.push(errorMsg);
    return strategies[strategy].apply(dom, arr);
  })
}

Validator.prototype.start = function() {
  for(var i=0; i < cache.length; i++) {
    var msg = this.cache[i]();
    if(msg) {
      return msg;
    }
  }
}


var todoFunc = function() {
var validator = new Validator();
  validator.add(registerForm.userName, 'isNonEmpty', 'User name cannot be empty');
  validator.add(registerForm.password, 'minLength:6', 'Password length should not be less than 6 bits');
  validator.add(registerForm.phoneNum, 'isMobile', 'Incorrect format of mobile phone number');
  var errorMsg = validator.start();
  return errorMsg;
}

var registerForm = document.getElementById('registerForm');
registerForm.onsubmit = function() {
  var errorMsg = todoFunc();
  if(errorMsg) {
    alert(errorMsg);
    return false;
  }
}

Posted by zelot1980 on Fri, 19 Apr 2019 17:57:33 -0700