JavaScript Design Mode for Refining Internal Work

Keywords: Javascript JQuery Attribute supervisor

Sensation:

Taste: Black pepper steak

Cooking time: 20 min

To be a good software developer, you need strong craftsmanship.When you encounter problems, find ways to solve them.Most people rely more on passion in the early stages, but need some patience in the middle and late stages.

After working for a long time, it is natural to think about the software system and face a challenge of your career.Do you want to be a technology leader?

Of course, the person in charge of technology should consider the problem from a larger perspective, so design mode is a required course, learning design mode can not only provide us with problem solving ideas in the daily business code.Design patterns are ubiquitous in architecture.

It's a high return, long half-life thing that deserves to be kept up.

Say nothing more. Start your meal now!

This paper describes behavioral design patterns, including template method pattern, observer pattern, status pattern, strategy pattern, responsibility chain pattern, command pattern, visitor pattern, mediator pattern, memo pattern, iterator pattern, interpreter pattern.

Template Method Pattern

Concepts: A set of operation algorithm skeleton is defined in the parent class, and some implementation steps are deferred to the subclass so that the subclass can redefine some implementation steps in the algorithm without changing the algorithm structure of the parent class.

The core lies in the reuse of methods, encapsulating the core methods in the base class, letting subclasses inherit the methods of the base class, sharing the methods of the base class, and making the methods common.

class canteen {
  eat () {
    eat1();
    eat2();
    eat3();
  }
  eat1 () {
    console.log('Seabed salvage');
  }
  eat2 () {
    console.log('Japanese cuisine');
  }
  eat3 () {
    console.log('barbecue');
  }
}

Application examples:

1. "It takes three steps to put an elephant in the refrigerator" is a top level logic, which may be implemented differently depending on the size of the refrigerator.

2. Make coffee and tea.

3. Template snippet functions in IDE s such as VS Code and Webstorm.

4. Cake moulds

Observer in Observer mode

Concept: Also known as publish-subscribe mode or messaging mechanism, it defines a dependency relationship that solves the functional coupling between the principal object and the observer.

Furthermore, the observer mode defines a one-to-many dependency between objects, and when the state of an object changes, all objects that depend on it are notified and automatically updated.

Application examples:

1. At an auction, the auctioneer is the observer who observes the highest bid and notifies other bidders to bid.

2. Native support for this pattern is implemented in Nodejs through EventEmitter.

trigger/on in jquery.

4.MVVM.

5. WeChat Public Number Push Article.

Take the WeChat Public Number as an example. You (different observers) are interested in the front-end canteen (one subject), and when the public document is updated (the subject is updated), you can all receive my push (observer).

// Subject is a public number principal that maintains an array of observers for the subscription.
// new Subject() creates a new public number
// addObserver Add Observer
// removeObserver Delete Observer
// inform notifies observers
function Subject() {
  this.observers = [];
}
Subject.prototype.addObserver = function (observer) {
  this.observers.push(observer);
}
Subject.prototype.removeObserver = function (observer) {
  let index = this.observers.indexOf(observer);
  if (index > -1) {
    this.observers.splice(index, 1);
  }
}
Subject.prototype.inForm = function () {
  this.observers.forEach(observer=>{
    observer.update();
  })
}
function Observer (name) {
  this.name = name;
  this.update = function () {
    console.log(name + 'update...');
  }
}

let subject = new Subject();
let observer1 = new Observer('fans1');
subject.addObserver(observer1);
let observer2 = new Observer('fans2');
subject.addObserver(observer2);
subject.inForm();

// fans1 update...
// fans2 update...
// Here's how ES6 is written. Thanks for paying attention to the bitch in the front canteen. Cough, baby~
class Subject {
  constructor () {
    this.observers = [];
  }
  addObserver (observer) {
    this.observers.push(observer);
  }
  removeObserver (observer) {
    let index = this.observers.indexOf(observer);
    if (index > -1) {
      this.observers.splice(index, 1);
    }
  }
  inForm () {
    this.observers.forEach(observer=> {
      observer.update();
    })
  }
}
class Observer {
  constructor (name) {
    this.name = name;
    this.update = function () {
      console.log(name + 'Kiss...');
    }
  }
}
let subject = new Subject();
let observer1 = new Observer('baby1');
subject.addObserver(observer1);
let observer2 = new Observer('baby2');
subject.addObserver(observer2);
subject.inForm();

// baby1?
// baby2?

State Mode State

Concept: When an object's internal state changes, it causes its behavior to change, which looks like it has changed the object.

The purpose of the state mode is to simplify the branch judgment process.

Application examples:

1. The various states caused by heroic skills in LOL, such as silence, deceleration, confinement, flying, etc.

2. File upload has the status of scanning, uploading, pausing, uploading success, uploading failure, etc.

class HappyYasuo {
  constructor () {
    this._currentState = [];
    this.states = {
      q_key () {console.log('Chopping Flash')},
      w_key () {console.log('Wind Barrier')},
      e_key () {console.log('Chop ahead')},
      r_key () {console.log('The gale will break')}
    }
  }

  change (arr) {  // Change current action
    this._currentState = arr;
    return this;
  }

  go () {
    console.log('Trigger Action');
    this._currentState.forEach(T => this.states[T] && this.states[T]());
    return this;
  }
}

new HappyYasuo()
    .change(['q_key', 'w_key'])
    .go()                      // Trigger Action Chopping Steel Flash Barrier
    .go()                      // Trigger Action Chopping Steel Flash Barrier
    .change(['e_key'])
    .go()                      // Trigger action beforehand chopping

##Policy Mode Strategy
Concept: Encapsulate a defined set of algorithms so that they can be replaced with each other.The encapsulated algorithm is independent and does not change with the client.

Application examples:

1. Zhuge Liang's brilliant ideas, each of which is a strategy.

2. Traveling by bicycle or by car is a strategy for each type of travel.

class ZhaoYun {
  constructor (type) {
    this.type = type;
  }
  plan () {
    if (this.type === 'first') {
      console.log('Open the first brocade');
    } else if (this.type === 'second') {
      console.log('Open the second brocade');
    } else if (this.type === 'third') {
      console.log('Open the third brocade');
    }
  }
}
var u1 = new ZhaoYun('first');
u1.plan();
var u2 = new ZhaoYun('second');
u2.plan();
var u3 = new ZhaoYun('third');
u3.plan();
class FirstStep {
  plan () {
    console.log('Open the first brocade');
  }
}
class SecondStep {
  plan () {
    console.log('Open the second brocade');
  }
}
class ThirdStep {
  plan () {
    console.log('Open the third brocade');
  }
}

var u1 = new FirstStep();
u1.plan();
var u2 = new SecondStep();
u2.plan();
var u3 = new ThirdStep();
u3.plan();

Responsibility Chain of Responsibility

Concepts: Resolves the coupling between the sender of the request and the recipient of the request, splits the request process by multiple objects in the chain of blame, and transfers the request among multiple objects until the last object completes processing the request.

Application examples:

1. Event bubbles in JavaScript.

2. Mission building in the twelfth hour of Chang'an.

// Leave approval requires group leader approval, manager approval, and final supervisor approval
class Action {
  constructor (name) {
    this.name = name;
    this.nextAction = null;
  }
  setNextAction (action) {
    this.nextAction = action;
  }
  handle () {
    console.log(`${this.name} Approval`)
    if (this.nextAction != null) {
      this.nextAction.handle();
    }
  }
}

let a1 = new Action('Group leader');
let a2 = new Action('manager');
let a3 = new Action('Chief inspector');
a1.setNextAction(a2);
a2.setNextAction(a3);
a1.handle();

Command Mode Command

Concepts: Decouple and encapsulate requests and implementations into separate objects so that different requests parameterize the implementation of the client.

That is, when a command is executed, the publisher and the executor are separated, and command objects are added in the middle to act as transit stations.

Application examples:

Instances of command mode are common in life, so let's just give you one example to imagine.

We go to the restaurant to order food (publisher), don't need to know the cook's name (executor), just tell the waiter (transit station).

// Recipient Chef
class Receiver {
  go () {
    console.log('Recipient Executes Request');
  }
}
// Command Object Server
class Command {
  constructor (receiver) {
    this.receiver = receiver;
  }
  action () {
    console.log('Command Object->recipient->Corresponding Interface Execution');
    this.recerver.go();
  }
}
// Publisher Customer Dining Orders
class Invoker {
  constructor (command) {
    this.command = command;
  }
  invoke () {
    console.log('Publisher Publish Request');
    this.command.action();
  }
}

let cook = new Receiver();
let waiter = new Command(cook);
let Diner = new Invoker(waiter);
Diner.invoke();

Visitor Mode Visitor

Concepts: Defines a new way to access elements in an object structure without changing the object.

Visitor mode is the separation of data operations from data structures.

Application examples:

You are a visitor at a friend's house. A friend accepts your visit. You pass on a friend's description and make a judgment about it. This is the visitor pattern.

Using the visitor mode, we can make objects have push, pop, and splice methods like arrays.

var Visitor = (function() {
      return {
        splice: function(){
          // splice method parameter, starting with the second parameter of the original parameter
          var args = Array.prototype.splice.call(arguments, 1);
          // Execute splice method on first parameter object
          return Array.prototype.splice.apply(arguments[0], args);
        },
        push: function(){
          // Enhance the class array object so that it has the length attribute
          var len = arguments[0].length || 0;
          // The data added starts with the second parameter of the original parameter
          var args = this.splice(arguments, 1);
          // Correct length attribute
          arguments[0].length = len + arguments.length - 1;
          // Execute push method on first parameter object
          return Array.prototype.push.apply(arguments[0], args);
        },
        pop: function(){
          // Execute pop method on first parameter object
          return Array.prototype.pop.apply(arguments[0]);
        }
      }
    })();

Mediator mode

Concepts: Encapsulates the interaction between a series of objects through a mediator object, eliminating their mutual reference and reducing their coupling.

Application examples:

1. Before China joined the WTO, all countries traded with each other, and the structure was complex. Now all countries trade with each other through the WTO.

2. Airport dispatching system.

3.MVC framework, where C (controller) is the intermediary between M (model) and V (view).

class Mediator {
  constructor (a, b) {
    this.a = a;
    this.b = b;
  }
  setA () {
    let number = this.b.number;
    this.a.setNumber(number * 100);
  }
  setB () {
    let number = this.a.number;
    this.b.setNumber(number / 100);
  }
}

class A {
  constructor () {
    this.number = 0;
  }
  setNumber (num, m) {
    this.number = num;
    if (m) {
      m.setB();
    }
  }
}

class B {
  constructor () {
    this.number = 0;
  }
  setNumber (num, m) {
    this.number = num;
    if (m) {
      m.setA();
    }
  }
}

Memento Mode

Concepts: Capture and save the internal state of an object outside of it, without destroying its encapsulation, so that it can be used later or the object can be restored to a previous state.

Application examples:

When paging components, click on the next page to get new data, but when you click on the previous page, you retrieve the data again, causing unnecessary waste of traffic, when you can cache the data.

// Memento memo objects are for primary use only with the Provided State Extraction method
var Memento = function(state){
    var _state = state;
    this.getState = function(){
        return _state;
    }
}
// Originator Primary
var Originator = function(){
    var _state;
    this.setState = function(state){
        _state = state;
    }
    this.getState = function(){
        return _state;
    }
    // saveStateToMemento Creates a memo to store the current state
    this.saveStateToMemento = function(){
        return new Memento(_state);
    }
    this.getStateFromMemento = function(memento){
        _state = memento.getState();
    }
}
// The responsible person is responsible for keeping the memo but cannot operate on or inspect its contents
var CareTaker = function(){
    var _mementoList = [];
    this.add = function(memento){
        _mementoList.push(memento);
    }
    this.get = function(index){
        return _mementoList[index];
    }
}
 
var originator = new Originator();
var careTaker = new CareTaker();
originator.setState("State 1");
originator.setState("State 2");
careTaker.add(originator.saveStateToMemento());
originator.setState("State 3");
careTaker.add(originator.saveStateToMemento());
originator.setState("State 4");
 
console.log("current state: " + originator.getState());
// Current status: State 4
originator.getStateFromMemento(careTaker.get(0));
console.log("Restore first saved state: " + originator.getState());
// Restore first saved state: State 2
originator.getStateFromMemento(careTaker.get(1));
console.log("Restore Second Save: " + originator.getState());
// Restore second save: State 3

Limitations: Memo mode consumes too much resources.

Iterator mode Iterator

Concept: The elements within an aggregated object can be accessed sequentially without exposing its internal structure.

This pattern is used to sequentially access the elements of a collection object without knowing the underlying representation of the collection object.

Application examples:

Iterators are built into most languages.

1. Array.prototype.forEach for JavaScript

2.jQuery $.each

$.each([1, 2, 3], function(i ,n){
  console.log('The current subscript is: '+ i,'The current value is:' + n);
})
// Subscript: 0 Current value: 1 
// Subscript: 1 Current value: 2  
// Subscript: 2 Current value: 3

There are also Iterator s in ES6

Interpreter mode

Concepts: For a language, give its grammatical representation and define an interpreter that can be used to interpret sentences defined in the language.

This pattern implements an expression interface that interprets a specific context.

Application examples:

1. Compiler

2. Regular expressions

Reference resources:

JavaScript Design Patterns Zhang Rongming

<br/>

Communication

Welcome to my Personal Public Number. Articles will be sent synchronously and a large amount of learning materials will be received free of charge in the background reply.

Your front dining hall, remember to eat on time.

Posted by zeropaid on Mon, 11 Nov 2019 19:17:53 -0800