This is the fourth day of my participation in Gwen Challenge

preface

Having introduced the prototype pattern and the singleton pattern, let’s move on to the policy pattern.

Policy Pattern Definition

When we use some navigation software, if we go from point A to point B, the navigation software will use different algorithms to calculate the path from point A to point B according to different conditions, but ultimately achieve the same goal. This is the embodiment of the strategic pattern.

The strategy pattern is to define a set of algorithms, encapsulate them one by one, and make them interchangeable.Copy the code

For example, when using the navigation system, different paths can be matched according to different conditions. So it can be done like this:

    
    // Path algorithm class A
    function PathPolicyA() {}
    PathPolicyA.prototype.calculate = function(type) {
        return 'policyA';
    }
    
    // Path algorithm class B
    function PathPolicyB() {}
    PathPolicyB.prototype.calculate = function(type) {
        return 'policyB';
    }
    
    / / path
    function Path() {
        this.path = null;
        this.policy = null;
    }
    
    Path.prototype.setPolicy = function(policy) {
        this.policy = policy;
    }
    
    // Get different paths according to different types
    Path.prototype.getPath = function() {
        return this.policy.calculate();
    }
    
    const p = new Path();
    
    p.setPolicy(new PathPolicyA());
    console.log(p.getPath()); // policyA
    
    p.setPolicy(new PathPolicyB());
    console.log(p.getPath()); // policyB

Copy the code

The above code is an implementation of the policy pattern in a traditional object-oriented language. It sets different policies through setPolicy, calls the calculate method of the corresponding policy class through getPath, and finally returns the path.

JavaScript policy pattern

Although the above code implements the policy pattern, it seems a bit cumbersome to implement in JS. Creating an object in JavaScript is very straightforward, and the object can be a function. This solves the above problem by defining only one object:

    var policyObj = {
        A: () = > 'policyA'.B: () = > 'policyB',}function getPath(policyObj, type) {
        if (policyObj[ type ] && typeof policyObj[ type ] === 'function') {
            return policyObj[ type ]();
        }
        return 'policy is not found';
    }
    
    console.log(getPath(policyObj, 'A')); // policyA
    console.log(getPath(policyObj, 'B')); // policyB
Copy the code

This code is consistent with the above method action, and this code looks more concise, we just need to define an object to load all the policies, according to different conditions to call different methods. The code above illustrates the core of the strategy pattern: define a set of algorithms, encapsulate them one by one, and make them interchangeable

Make form validation using the policy pattern

By definition, it seems that the policy pattern is used to encapsulate algorithms. In fact, it can also be extended to encapsulate business rules, such as form validation

var policy = {
    // Mandatory verification
    isEmpty: ({ val }) = >!!!!! val,// Maximum length check
    maxLength: ({ maxLen, val }) = > val.length < maxLen,
    // Only digit check
    isNumber: ({ val }) = > / ^ [0-9] * $/.test(val),
}

function varifyForm(formData, formRule) {
    // Loop the form object
    for(let x in formData) {
        // Fields are validated only if they have defined rules
        if (formRule[ x ]) {
            const tmpVal = formData[ x ];
            // Loop validation rules
            for(let rule of formRule[ x ]) {
                // Only defined policies are validated
                if (policy[ rule.type ]) {
                    constparam = {... Object.assign(rule.param || {}, {val: tmpVal })}
                    const isAccept = policy[ rule.type ](param)
                    if(! isAccept)return {
                        accept: false.msg: rule.errMsg || `${ x } varify fail`,}}}}}return {
        accept: true.msg: ' ',}}// Define test cases
var form1 = {
    a: null,}var form2 = {
    a: 213213123,}var form3 = {
    a: 'd212',}var rules = {
    a: [{type: 'isEmpty'.errMsg: 'a is Empty'
        },
        {
            type: 'maxLength'.errMsg: 'a is too long'.param: { maxLen: 5}, {},type: 'isNumber'.errMsg: 'a is not a number',]}}console.log(varifyForm(form1, rules)); // a is Empty
console.log(varifyForm(form2, rules)); // a is too long
console.log(varifyForm(form3, rules)); // a is not a number
Copy the code

In the above code, the policy is an object that defines the policy, and the varifyForm validates the main method of the form, validating the rules defined by each field by passing in form data and form fields. Finally, the verification result is returned.

Talk about policy patterns in JavsScript

In JavaScript, functions are first-class objects, and the policy pattern here, like the prototype pattern, is integrated into the JavaScript language itself. Although it is a relatively “transparent” pattern in JavaScript, understanding the policy pattern can help us design functions and understand JavaScript.

There are certain advantages to using the policy pattern:

1. The use of delegation, combination and other technologies can effectively avoid conditional selection statements. 2. The algorithm is independently encapsulated in an object or class, making it easier to switch, understand and expand.Copy the code

summary

This article introduces the concept and benefits of policy patterns, as well as examples of using policy patterns in JavaScript.

The strategy pattern is to define a series of algorithms, encapsulate them one by one, and make them interchangeable

JavaScript Design Patterns other articles 1. Prototype patterns 2. Singleton patterns for design patterns

If you find this article helpful, you can encourage the author by clicking a “like”, and if you want to learn more about JavaScript or Node, you can click here. Please point out any inaccuracies or errors in the comments section.

reference

  1. JavaScript design patterns and development practices