Common Design Patterns for javascript

  • 2021-07-18 06:48:10
  • OfStack

js is preferably an object-oriented language. It appeared later. But it is the hottest scripting language at present. Moreover, with the recent rise of WeChat Mall and other pages, I believe programmers and Internet practitioners know that js is gaining momentum.

Then, if you want to go further on the front-end road, the design pattern must be understood. Here are some common design patterns.

1. Singleton pattern

Singleton pattern is also called monad pattern, and more is also called monomer pattern. It is a simple but most commonly used design pattern in software design. In JavaScript, there are many ways to implement singletons, among which the simplest way is to use the literal quantity of objects, which can contain a large number of attributes and methods:


var mySingleton = {
property1: "something",
property2: "something else",
method1: function () {
  console.log('hello world');
}};

If you want to extend the object later, you can add your own private members and methods, and then use closures to encapsulate these variables and function declarations inside them. Expose only the public members and methods you want to expose. The sample code is as follows:


 var mySingleton = function () {
  /*  Private variables and methods are declared here  */
  var privateVariable = 'something private';
  function showPrivate() {
    console.log(privateVariable);
  }
  /*  Public variables and methods (private variables and methods can be accessed)  */
  return {
    publicMethod: function () {
      showPrivate();
    },
    publicVar: 'the public can see this!'
  };
};
var single = mySingleton();
single.publicMethod(); //  Output  'something private'
console.log(single.publicVar); //  Output  'the public can see this!'

The above code is good, but what if we want to initialize it only when we use it? To save resources, we can initialize these codes in another constructor, as follows:


var Singleton = (function () {
  var instantiated;
  function init() {
    /* The singleton code is defined here */
    return {
      publicMethod: function () {
        console.log('hello world');
      },
      publicProperty: 'test'
    };
  }
  return {
    getInstance: function () {
      if (!instantiated) {
        instantiated = init();
      }
      return instantiated;
    }
  };
})();
/* Call a public method to get an instance :*/
Singleton.getInstance().publicMethod();

2. Factory model

Factory pattern is a method that determines which class instances to create, often with the same interface. This pattern is mainly used when the type being instantiated is not determined at compile time, but is determined at execution time. To put it more popularly, like the beverage machine in the company pantry, whether you want coffee or milk depends on which button you press.

Example:


function A( name ){
       this.name = name;
    }
    function ObjectFactory(){
       var obj = {},
           Constructor = Array.prototype.shift.call( arguments );
obj.__proto__ = typeof Constructor .prototype === 'number' ? Object.prototype
: Constructor .prototype;
       var ret = Constructor.apply( obj, arguments );
       return typeof ret === 'object' ? ret : obj;
    }
    var a = ObjectFactory( A, 'svenzeng' );
    alert ( a.name ); //svenzeng

This code comes from the relevant instructions of new and constructor of es5. It can be seen that the so-called new itself is only a process of copying and rewriting an object, and what will be generated is determined by the parameters passed in when calling ObjectFactory.

3. Adaptation mode

Simply put, the adaptation mode is mainly to solve the problem of incompatible interfaces. With the help of adapters, we can provide the user with the wrapped adapter interface of the system 1 without modifying these incompatible interfaces. On the surface, it feels similar to the previous facade mode, which wraps and re-presents other objects or interfaces, while the adapter mode tends to solve compatibility problems, while the facade mode tends to be convenient.

For example, a simple method for students to inquire about subject scores:


  function selectScore( name, id, course_id ){
  // arguments  Name   Student number   Curriculum id
  ...
}

When I need an overall grade list of a subject in a class, I only have the following data for each student


[
  { name: 'lily', studentID: '0911' },
  { name: 'suny', studentID: '0912' },
  ...
]

I need to query English whose course ID is 101, so it is very appropriate to write an adapter for this task


function selectEnglishScore( stutentObj ){
  selectScore( stutentObj.name, stutentObj.studentID , 101);
}

This is one of the simplest compatible forms about adapters to handle parameters. In fact, simply speaking, the adapter pattern is very simple-adapting and solving compatibility problems.

Example 2, for example, if you think the $selector in jquery needs to be changed to $id to match your project, it is easy to write a method to convert $to $id. As follows:


$id = function( id ){
 return jQuery( '#' + id )[0];
}

4. Appearance mode

Appearance mode (facade mode) is a relatively simple and ubiquitous mode. Appearance mode provides a high-level interface that makes it easier for clients or subsystems to call. It is represented by a simple piece of code:


var getName = function(){
 return ''svenzeng"
}
var getSex = function(){
  return 'man'
}

If you need to call getName and getSex functions respectively, you can call them with a higher level interface getUserInfo.:


var getUserInfo = function(){
 var info = a() + b();
 return info;
}

You may ask why 1 didn't start with getName and getSex, such as this:


 var mySingleton = function () {
  /*  Private variables and methods are declared here  */
  var privateVariable = 'something private';
  function showPrivate() {
    console.log(privateVariable);
  }
  /*  Public variables and methods (private variables and methods can be accessed)  */
  return {
    publicMethod: function () {
      showPrivate();
    },
    publicVar: 'the public can see this!'
  };
};
var single = mySingleton();
single.publicMethod(); //  Output  'something private'
console.log(single.publicVar); //  Output  'the public can see this!'
0

The answer is obvious. The cooking chef in the canteen will not stir-fry 1 roast duck and 1 cabbage in one pot just because you ordered them. He prefers to offer you a roast duck rice set meal. Also in programming, we need to ensure that functions or objects are at a reasonable granularity as much as possible. After all, not everyone likes roast duck and just likes cabbage. Another advantage of the facade pattern is that it can hide the real implementation details from the user, who only cares about the highest-level interface. For example, in the story of roast duck rice set meal, you don't care whether the master cooked roast duck or fried cabbage first, and you don't care where the duck grew up.

Finally, write an example of appearance patterns that we have all used:


 var mySingleton = function () {
  /*  Private variables and methods are declared here  */
  var privateVariable = 'something private';
  function showPrivate() {
    console.log(privateVariable);
  }
  /*  Public variables and methods (private variables and methods can be accessed)  */
  return {
    publicMethod: function () {
      showPrivate();
    },
    publicVar: 'the public can see this!'
  };
};
var single = mySingleton();
single.publicMethod(); //  Output  'something private'
console.log(single.publicVar); //  Output  'the public can see this!'
1

Ok, that's all for today's forehead design pattern. If you want to know more about design patterns, you can go to Uncle Tom's blog to enjoy it. Also, many design patterns here actually refine the solution to the problem. If you look at prototype or jquery, you will know that many of the codes inside actually use design patterns.


Related articles: