JS Design Mode 5 - Creative Design Mode: Prototype Mode, Policy Mode, Agent Mode

Keywords: Javascript Programming Web Development Attribute

Article Directory

Prototype mode

Prototype: Specifies the kind of objects created with prototype instances, and creates new objects by copying them.

This is particularly easy to implement because of the nature of JavaScript

//Parent Class
class Parent{
    constructor(x){
        this.x = x;
    }
    showX(){
        alert( this.x );
    }
}

//Subclass 1 Inheritance
class ChildA extends Parent{
    constructor(x,y){
        super();
        this.y = y;
    }
    showY(){
        alert( this.y );
    }
}
//Subclass 2 Inheritance
class ChildB extends Parent{
    constructor(x,z){
        super();
        this.z = z;
    }
    showZ(){
        alert( this.z );
    }
}

let obj = {
    sayHello(){
        alert( "Hello" );
    }
};

let objA = Object.create(obj,{
    name :{
        writable:true,
        configurable :true,
        enumerable:true,
        value : "AA"
    }
});

let objB = Object.create(obj,{
    name :{
        writable:true,
        configurable :true,
        enumerable:true,
        value : "BB"
    }
});

objA.sayHello()

Multiple classes use the same properties or methods, so we can create class or instance objects by prototype inheritance

Policy Mode

In reality, there are many ways to reach the same destination.

For example, if we are going to travel somewhere, we can choose the travel route according to the actual situation.

In programming, we often encounter similar situations where there are many options to achieve a certain function

These algorithms are flexible and versatile and can be replaced at will.This solution is the so-called strategy model.

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

Example

Different salaries for employees with different performance

A policy-based program consists of at least two components.

  1. The first part is a set of policy classes, which encapsulate specific algorithms and are responsible for the specific calculation process.
  2. The second part is the environment class Context, which accepts the client's request and then delegates it to a policy class.To do this, you need to maintain a reference to a policy object in the Context.
var strategies = {
    //Policy Class
    "S": function( salary ){
        return salary * 4;
    },
    "A": function( salary ){
        return salary * 3;
    },
    "B": function( salary ){
        return salary * 2;}
};
//Environment Class Context
var calculateBonus = function( level, salary ){//Accept customer's request
    return strategies[ level ]( salary );//Delegate Class
};

console.log( calculateBonus( 'S', 20000 ) ); // Output: 80000
console.log( calculateBonus( 'A', 10000 ) ); // Output: 30000

mtween slow motion animation

Now analyze the ideas for implementing this program.Before you start, you need to record some useful information in advance, including at least the following:

  • At the beginning of the animation, the original position of the ball;
  • The target position of the ball's movement;
  • The exact point in time at which the animation begins;
  • The duration of the ball movement.

Motion curve algorithm

  • C, b, D is constant, t is variable
    Let's assume that c is 2, b is 3, and t has a range of [0, d]

/*
* These are motion curves that simulate an approximate Bezier effect
* @t: Time consumed by animation
* @b: initial position
* @c: End position
* @d: Total duration of animation
* */
var tween = {
    linear: function (t, b, c, d) {
        return c * t / d + b;
    },
    easeIn: function (t, b, c, d) {
        return c * (t /= d) * t + b;
    },
    strongEaseIn: function (t, b, c, d) {
        return c * (t /= d) * t * t * t * t + b;
    },
    strongEaseOut: function (t, b, c, d) {
        return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
    },
    sineaseIn: function (t, b, c, d) {
        return c * (t /= d) * t * t + b;
    },
    sineaseOut: function (t, b, c, d) {
        return c * ((t = t / d - 1) * t * t + 1) + b;
    }
};

proxy pattern

Agent mode is to provide a substitute or placeholder for an object to control access to it

The key to the proxy mode is to provide a surrogate object to control access to an object when it is not convenient for the client to access it directly or when the client does not meet his or her needs. The client actually accesses the surrogate object.Substitute object handles the request before forwarding it to the ontology object

Protection Agent and Virtual Agent

  • This is the protection agent when a client's request to an agent is analyzed and found to be ineligible and rejected.
  • A virtual agent is a request sent by a client to an agent that requires the agent to determine certain conditions are met before the final instruction is sent to the target.

Example: Virtual agent for lazy picture loading

    <script>
        var myImage = (function () {
            var imgNode = document.createElement('img');
            document.body.appendChild(imgNode);
            return {
                setSrc: function (src) {
                    imgNode.src = src;
                }
            }
        })();

        var proxyImage = (function () {
            var img = new Image;
            img.onload = function () {
                myImage.setSrc(this.src);
            };
            return {
                setSrc: function (src) {
                    myImage.setSrc('./1.png');
                    img.src = src;
                }
            }
        })();

        proxyImage.setSrc('./2.png');

    </script>

Picture preloading is a common technique in Web development

If the src attribute is set directly to an img tag node, the location of the picture will be blank for some time because the picture is too large or the network is not good.

A common practice is to take a place with a loading picture and load the picture asynchronously

This scenario works well with virtual agents when the picture is loaded and then populated into the img node

Meaning of agency: principle of single responsibility

There should be only one reason for a class (usually objects, functions, etc.) to change.

If an object has multiple responsibilities, it means that the object will become enormous, and there may be multiple reasons for its changes.

Object-oriented design encourages the distribution of behavior among fine-grained objects, and if an object has too many responsibilities, it is equivalent to coupling those responsibilities together, which can lead to fragile and less cohesive designs.

When changes occur, the design may be accidentally damaged.

Cache Proxy

The cache proxy can provide temporary storage for some expensive operations, and in the next operation, if the parameters passed in are the same as before, the previously stored results can be returned directly.

var multi = function () {
    console.log('Start calculating the product');
    var a = 1;
    for (var i = 0, l = arguments.length; i < l; i++) {
        a = a * arguments[i];
    }
    return a;
};

var proxyMulti = (function () {
    var cache = {};
    return function () {
        var args = Array.prototype.join.call(arguments, ',');
        if (args in cache) {
            return cache[args];
        }
        return cache[args] = multi.apply(this, arguments);
    };
})();

console.log(proxyMulti(1, 2, 3, 4));
console.log(proxyMulti(1, 2, 3, 4));
Start calculating the product
24
24

Proxy es6 built-in proxy mode

Proxy is a new feature in ES6 that can be used to customize operations in objects.Proxy will replace the original in Vue3.0 Object.defineProperty To achieve data responsiveness.

let p = new Proxy(target, handler)

A target represents an object that needs to be proxied, and a handler is used to customize actions within the object, such as using a custom set or get function.

let onWatch = (obj, setBind, getLogger) => {
  let handler = {
    set(target, property, value, receiver) {
      setBind(value, property)
      return Reflect.set(target, property, value)
    },
    get(target, property, receiver) {
      getLogger(target, property)
      return Reflect.get(target, property, receiver)
    }
  }
  return new Proxy(obj, handler)
}

let obj = { a: 1 }
let p = onWatch(
  obj,
  (v, property) => {
    console.log(`Listening Properties${property}Change to${v}`)
  },
  (target, property) => {
    console.log(`'${property}' = ${target[property]}`)
  }
)
p.a = 2 // Console Output: Listen for property a changes
p.a // 'a' = 2

Customizing the set and get functions inserts our function logic into the original logic to notify you when any properties of the object are read or written.

Of course, this is a simple, responsive implementation. If you need to implement a responsive implementation in a Vue, you need us to collect dependencies in the get and distribute updates in the set. The reason why Vue3.0 uses Proxy to replace the original API is ProxyThis can be done one time without having to recursively add proxies for each property. The performance is better, and some data updates in the original implementation cannot be monitored, but Proxy can perfectly monitor any kind of data change. The only drawback may be that the browser is not compatible.

Posted by drew010 on Thu, 11 Jun 2020 19:20:29 -0700