The singleton pattern, also known as the monad pattern, is one of the creation patterns.

When this pattern is applied, the singleton class must ensure that only one instance exists. Many times the whole system only needs to have one global object, which helps us coordinate the behavior of the whole system.

For example, in a server program, the configuration information of the server is stored in a file. The configuration data is read by a singleton and then retrieved by other objects in the server process. This approach simplifies configuration management in complex environments.

The idea of realizing singleton pattern

A class can return a reference to an object (always the same) and a method to obtain the instance (it must be static, usually using the name getInstance).

When we call this method, we return the reference held by the class if it is not empty, and create an instance of the class if the reference held by the class is empty and assign the instance’s reference to the reference held by the class.

We also define the constructor of the class as a private method, so that code elsewhere cannot call the constructor to instantiate objects of the class, only to get a unique instance of the class through static methods provided by the class.

The following uses JavaScript to implement the singleton pattern:

var Singleton = function (name) { this.name = name; } Singleton.instance = null; Singleton.prototype.getName = function() { alert(this.name); } Singleton.getInstance = function(name) { if ( ! this.instance ) { this.instance = new Singleton(name); } return this.instance } var a = Singleton.getInstance('sven1'); var b = Singleton.getInstance('sven2'); alert( a === b ); Var Singleton = function(name) {this.name = name; } Singleton.prototype.getName = function() { alert( this.name ) } Singleton.getInstance = (function() { var instance = null; return function( name ) { if ( ! instance ) { instance = new Singleton(name); } return instance; }}) (); var a = Singleton.getInstance('sven1'); var b = Singleton.getInstance('sven2'); alert( a === b ); // trueCopy the code

It can be applied to thread pools, global caches, window objects in browsers, floating Windows.

The practice of the Javascript singleton pattern

Global variables conform to this singleton pattern, but it is necessary to minimize their use and, if necessary, to minimize their contamination.

1. Use namespaces
var namespace1 = { a: function() { alert(1); }, b: function() { alert(2); }}Copy the code
Create namespaces dynamically
var MyApp = {}; MyApp.namespace = function( name ) { var parts = name.split('.'); var current = MyApp; for( var i in parts) { if ( ! current[ parts[i] ] ) { current[ parts[ i ]] = {} } current = current[ parts[ i ] ]; }}; MyApp.namespace('event'); MyApp.namespace('dom.style'); console.dir( MyApp ); Var MyApp = {event: {}, dom: {style: {}}}Copy the code
2. Encapsulate private variables with closures
var user = (function() {
  var __name = 'sven',
      __age = 29;
  
  return {
    getUserInfo: function() {
      return __name + '-' + __age
    }
  }
})
Copy the code

Inert singleton

The instance instance object is always created when we call singleton.getInstance, not when the page loads, so we can implement a lazy Singleton.

Singleton.getInstance = (function() {
  var instance = null;
  return function( name ) {
    if ( !instance ) {
      instance = new Singleton( name );
    }
    return instance;
  }
})
Copy the code

Generic lazy singleton

var createIframe = (function() {
  var iframe;
  return function() {
    if (!iframe) {
      iframe = document.createElement('iframe');
      iframe.style.display = 'none';
      document.body.appendChild(iframe);
    }
    return iframe;
  }
})
Copy the code

Pull away

var getSingle = function(fn) { var result; return function() { return result || (result = fn.apply(this, arguments)); }}Copy the code

example

var createLoginLayer = function () { var div = document.createElement('div'); Div. InnerHTML = 'I'm logged in to float window '; div.style.display = 'none'; document.body.appendChild(div); } var createSingleLoginLayer = getSingle(createLoginLayer); document.getElementById('loginBtn').onClick = function() { var loginLayer = createSingleLoginLayer(); loginLayer.style.display = 'block'; }Copy the code

Advantages and disadvantages of the singleton pattern

Advantages:

  1. You can guarantee only one instance of a class.
  2. You get a global access node that points to the instance.
  3. A singleton is initialized only when it is first requested.

Disadvantages:

  1. A violation of theSingle responsibility principle. This pattern solves two problems simultaneously.
  2. The singleton pattern can mask bad design, such as too much knowledge between the components of a program.
  3. Singleton client-side code unit testing can be difficult because many testing frameworks create mock objects in an inheritance-based manner. Because the constructor of a singleton class is private, and most languages can’t override static methods, you need to come up with ways to simulate singletons carefully. Either don’t write the test code at all, or don’t use the singleton pattern.

Public account @ front-end growth manual