Fine javascript Design Mode (strategy mode)

I try to explain all aspects of the design pattern in the least amount of text and space.
Full Text Connection

Understanding Strategic Patterns

Split the algorithm from the part calling it

Let me give you an example: You want to travel to Sanya in many ways: by plane, by train, by car.These methods can all reach the destination, but the process is different.

  • Airplane: Suitable for emergency money
  • Train: suitable for non-emergency and clear purpose (company group building, middle-aged and elderly tourism)
  • Self-driving tour: This kind of more casual, go out with friends and family, enjoy the scenery passing by.

Each choice is a strategy.
Strategies in the program are meant to integrate code that handles different tasks but serves the same purpose.They are delegated with one more level of functionality to work with specific algorithms.This eliminates the large number of conditional branching statements in the original program

Code above: Policy mode (calculating arrival times for different modes of travel)

// Define policies
var strategies = {
    'plane': function(distance) {
        return distance * 1; // Assume that the airplane is the fastest
    },
    'train': function(distance) {
        return distance * 4; // The speed of an airplane is four times that of a train
    },
    'roadTrip': function(distance) {
        return distance * 10; // The speed of an airplane is 10 times that of a driving tour
    },
}

// Context
var calculateBonus = function(mode, distance) {
    if (typeof strategies[mode] === 'function') {
        return strategies[mode](distance);
    }
    return -1;
}

// Invoke Policy
console.log(calculateBonus('plane', 1000));
console.log(calculateBonus('train', 1000));
console.log(calculateBonus('roadTrip', 1000));
Strategic Patterns are easy to understand. Let's first look at a piece of code that will be transformed by Strategic Patterns.

Before using policy mode

var calculateBonus = function(mode, distance) {
    if (mode === 'plane') {
        return distance * 1;
    } else if (mode === 'train') {
        return distance * 4;
    } else if (mode === 'roadTrip') {
        return distance * 10;
    }
    return -1;
}

The biggest problem with this piece of code is that it is not reproducible enough to be maintained.Every time a new change occurs, the code must be scraped open to find a specific function to modify.Low efficiency, prone to consistency errors.

Use strategy mode to achieve slow understanding of animation functions

To clarify the scenario in which the strategy pattern is used, let's implement an animation function together.

The js animation principle changes the css properties of the dom, such as left, top, background-position.So at least provide some information.

  • dom initial position
  • Target location
  • start time
  • End time

Then, with the timer setInterval, the css property of the dom is changed once every 19 milliseconds in the timer, and the four parameters above are passed to the algorithm each time the dom is modified.The algorithm calculates where it should be.Finally, the css property of the dom is updated.This completes the animation.

Algorithmic section, originally from Flash, but now also from css3

Online Experience

// Define the animation slowdown algorithm first
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;
    }
}

Then add the next node to the body

<div style="position: absolute; background:yellow;">im div</div>

Next, define the animation class

let Animate = function(dom) {
    this.dom = dom;
    this.startTime = 0;
    this.startPos = 0;
    this.endPos = 0;
    this.propertyName = null;
    this.esing = null;
    this.duratin = null;
}
Animate.prototype.start = function(propertyName, endPos, duratin, esing) {
    this.startTime = Date.now();
    this.startPos = this.dom.getBoundingClientRect()[propertyName];
    this.propertyName = propertyName;
    this.endPos = endPos;
    this.duratin = duratin;
    this.esing = tween[esing];
    let self = this;
    let timeId = setInterval(function() {
        if (self.step() === false) {
            clearInterval(timeId)
        }
    }, 19)
}
Animate.prototype.step = function() {
    var t = Date.now();
    if (t >= this.startTime + this.duratin) {
        this.update(this.endPos)
        return false
    }
    var pos = this.esing(
        t - this.startTime, // time
        this.startPos, // Beginning value
        this.endPos - this.startPos, // Motion Distance
        this.duratin // Time taken for tests
    )
    this.update(pos);
}
Animate.prototype.update = function(pos) {
    this.dom.style[this.propertyName] = pos + 'px';
}

To test it!

var div = document.getElementsByTagName('div')[0];
var animate = new Animate(div);

animate.start('left', 500, 1000, 'linear')
// animate.start('left', 500, 1000, 'easeIn')
// animate.start('left', 500, 1000, 'strongEaseIn')
// animate.start('left', 500, 1000, 'strongEaseOut')
// animate.start('left', 500, 1000, 'sineaseIn')
// animate.start('left', 500, 1000, 'sineaseOut')

Keywords: Javascript css3

Added by ihcra on Mon, 22 Jun 2020 03:06:10 +0300