define

The policy pattern is a common and effective design pattern. It refers to defining a set of algorithms, encapsulating them one by one, and making them interchangeable. The essence of the strategy pattern is to separate the use of algorithms from their implementation. A basic strategy pattern consists of the following two parts:

  1. A set of policy classes that encapsulate a specific algorithm and are responsible for its implementation.
  2. The environment classContext, which accepts the client’s request and delegates the request to a policy class.

The advantages and disadvantages

The strategic mode has the following advantages:

  • usingcombination,entrust,polymorphismAnd so on, effectively avoid multiple conditional selection statements.
  • Provides forOpen-closedPerfect support for principles, easy to understand and extend using policy branch functions.
  • combination,entrustThe way also letContextYou have the basic ability to execute algorithms.
  • High reusability.

The disadvantages of the policy pattern are not obvious, mainly in that the application needs to maintain more policy objects, but in essence, the advantages outweigh the disadvantages.

The sample

In Javascript, functions as first-class citizens are themselves objects, so we use objects to implement the policy pattern.

// part 1
var strategies = {
  S: function(salary) {
    return salary * 4;
  },
  A: function(salary) {
    return salary * 3;
  },
  B: function(salary) {
    return salary * 2; }},// part 2
var calculateBouns = function(level, salary) {
  return strategies[level](salary);
};

console.log(calculateBouns('S'.2000));
console.log(calculateBouns('A'.800));
Copy the code

scenario

Form validation

In daily form interaction, we will encounter various input items bound with corresponding form verification rules. If it is time-consuming and redundant to write corresponding rules for each input item, we can adopt the policy mode for transformation.

var strategies = {
  isNonEmpty(value, errorMsg) {
    if(value === ' ' || value == null) {
      returnerrorMsg; }},minLength(value, length, errorMsg) {
    if(value.length < length) {
      returnerrorMsg; }},isMobile(value, errorMsg) {
    if(!/ 1 [3] [5] [8] [0-9] {9} $/.test(value)) {
      returnerrorMsg; }}},Copy the code

After completing the rule mapping table for the form, create a new Validator class for rule validation. The Validator class here acts as the Context, receiving user requests and delegating them to strategies to match the corresponding rules.

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

Validator.prototype.add = function(value, rule, errorMsg) {
  var arr = rule.split(':');
  this.cache.push(
    function() {
      var stratery = arr.shift();
      arr.unshift(value);
      arr.push(errorMsg); // [44, "isMobile", 'mobile number format is incorrect ']
      return strategies[stratery].apply(this, arr)
    }
  )
}

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

/ / use
var validator = new Validator();

validator.add('13136199370'.'isMobile'.'Mobile phone number format is not correct');
validator.add('12'.'minLength: 6'.'Password length must not be less than 6 characters');

var errMsg = validator.start();
console.log(errMsg);

Copy the code