JavaScript patterns: Throttle and Debounce

JavaScript patterns: Throttle and Debounce

In this article, we’ll cover two JavaScript patterns to control the repeated call of event handlers: throttle and debounce.

Do you need to handle a specific event, but you want to control how many times your handler will be called in a given period of time? This is a very common problem and often happens when listening to events such as scroll, mousemove or resize, which are triggered dozens of times a second. But sometimes it’s desirable even for less “frenetic” events, like, for example, to limit an action that occurs when a certain button is clicked.

The example app

In order to understand both patterns, we will use a simple example application that shows the current mouse coordinates in the screen and how many times these coordinates were updated. By looking at this counter, you will find it easier to compare how these two techniques can control the calling of an event handler. This is our app without any event control technique applied:

render();

document.body.addEventListener('mousemove', logMousePosition);

let callsCount = 0;
const positionsEl = document.querySelector('.app__positions');
function logMousePosition(e) {
  callsCount++;
  positionsEl.innerHTML = `
    X: ${e.clientX},
    Y: ${e.clientY},
    calls: ${callsCount}
  `;
}

function render() {
  document.querySelector('#app').innerHTML = `
    # Mouse position (Without event control)

    

  `;
}

And here is how this initial version of our app behaves:

Full example.

Did you notice the calls count? In just 7 seconds, the logMousePosition function was called 320 times! Sometimes you don’t want a given event handler to be called so many times in a period of time so short. Now, let’s see how to solve this issue.

Throttle

The throttle pattern limits the maximum number of times a given event handler can be called over time. It lets the handler be called periodically, at specified intervals, ignoring every call that occurs before this wait period is over. This technique is commonly used to control scrolling, resizing and mouse-related events.

We need to adapt the example app to use the throttle pattern. In order to do so, let’s change the addEventListener call of the original code to include the throttling logic:

let enableCall = true;
document.body.addEventListener('mousemove', e => {
  if (!enableCall) return;

  enableCall = false;
  logMousePosition(e);
  setTimeout(() => enableCall = true, 300);
});

In the above code:

  1. We’re declaring a enableCall variable to control if the throttling interval is already over. This flag is initially set to true, in order to allow the handler to be called the first time.
  2. Every time a mousemove event is triggered, we test if the enableCall variable is true. If not, that means that the minimum wait period is not over yet and we won’t call the event handler that time.
  3. However, if the enableCall variable is true, we can execute the event handler normally. However, before doing so, we need to set our control flag to false in order to prevent the handler to be called again during the wait interval.
  4. After calling the event handler, we use the setTimeout function to set our flag back to true after 300 milliseconds. This way, our handler will only be authorized to run again when this minimum interval is over.

Full example.

Now, let’s see how the app behaves after applying this technique:

The throttling logic works perfectly! Now, there’s a minimum interval of 300 milliseconds between the updates, drastically reducing our calls count.

A reusable throttle function

In order to make this code reusable, let’s extract it to a separate function:

document.body.addEventListener('mousemove', throttle(logMousePosition, 300));

function throttle(callback, interval) {
  let enableCall = true;

  return function(...args) {
    if (!enableCall) return;

    enableCall = false;
    callback.apply(this, args);
    setTimeout(() => enableCall = true, interval);
  }
}

The logic here is the same as above. When called, the throttle function returns a new event listener. In this version, we’re using a common function in order to preserve the original this context and apply it to the passed callback.

Full example.

Debounce

The debounce pattern allows you to control events being triggered successively and, if the interval between two sequential occurrences is less than a certain amount of time (e.g. one second), it completely ignores the first one. This process is repeated until it finds a pause greater than or equal to the desired minimum interval. Once it happens, only the last occurrence of the event before the pause will be considered, ignoring all the previous ones. A common use case for this pattern is to limit requests in a search box component that suggests topics while the user is typing.

Let’s adapt our example app to use the debounce pattern:

let debounceTimeoutId;
document.body.addEventListener('mousemove', (e) => {
  clearTimeout(debounceTimeoutId);
  debounceTimeoutId = setTimeout(() => logMousePosition(e), 300);
});

The above piece of code contains the essence of the debounce pattern. Every time the event we want to control is fired, we schedule a call to the handler for 300 milliseconds later (by using setTimeout) and cancel the previous scheduling (with clearTimeout). This way, we’re constantly delaying the execution of the handler function until the interval between two sequential events is equal to or greater than a given threshold time.

To sum up:

Let’s say we have a given event being triggered two times (A and B) and there’s an X interval between these two occurrences. If we want to control this event by applying a debounce of Y milliseconds, here’s how it will work:

  • If X < Y, the A call will be ignored.
  • If X >= Y, the B call is considered.
  • In both cases, if the new interval after B is greater than or equal to Y, B will be considered too.

Now, let’s see how it behaves in practice:

Full example

A reusable debounce function

Finally, we can extract the pattern logic to a reusable function. This way, we can easily apply it in similar situations in the future:

document.body.addEventListener('mousemove', debounce(logMousePosition, 300));
function debounce(callback, interval) {
  let debounceTimeoutId;

  return function(...args) {
    clearTimeout(debounceTimeoutId);
    debounceTimeoutId = setTimeout(() => callback.apply(this, args), interval);
  };
}

Full example

Conclusion
  • The debounce pattern delays the calling of the event handler until a pause happens. This technique is commonly used in search boxes with a suggest drop-down list. By applying this pattern, we can prevent unnecessary requests to the backend while the user is typing.
  • The throttle pattern is more suitable for events that are triggered many times in a short period of time. This technique is normally used to control scrolling, resizing and mouse-related events. By using throttle, we can filter repeated executions of an event handler, enforcing a minimum wait time between calls.

10 JavaScript Design Patterns You Should Know

10 JavaScript Design Patterns You Should Know

In this post, I want to discuss top 10 JavaScript design patterns to expose ways to improve your programming repertoire and dive deeper into the JavaScript internals.

Every developer strives to write maintainable, readable, and reusable code. Code structuring becomes more important as applications become larger. Design patterns prove crucial to solving this challenge - providing an organization structure for common issues in a particular circumstance.

JavaScript web developers frequently interact with design patterns, even unknowingly, when creating applications.

Although there is a diverse list of design patterns used in certain circumstances, JavaScript developers tend to use some patterns customarily more than others.

In this post, I want to discuss these common patterns to expose ways to improve your programming repertoire and dive deeper into the JavaScript internals.

1. The constructor Pattern

In classical object-oriented programming languages, a constructor is a special method used to initialize a newly created object once the memory has been allocated for it. In JavaScript almost everything is an object, we have most often interested in object constructors. Since object constructors are used to creating specific types of objects, for example, both preparing the object for use and accepting arguments a constructor can use to set the values of member properties and methods when the object is first created.

As we saw know JavaScript does not support the concept of classes, so inside a constructor, the keyword this references the new object that's being created revisiting object creation, a basic constructor may look as follows:

function Car(model, year, miles) {
  this.model = model;
  this.year = year;
  this.miles = miles;
}

// Usage:
var bmw = new Car('M4', '2019', '1000');

2. The module Pattern

Modules are an integral piece of any robust application's architecture and typically help in keeping the unit of code for a project cleanly separated and organized
There are several option for implementing modules. These include:

  • Object literal notation
  • The module Pattern
  • AMD modules
  • CommonJS module
  • ECMAScript Harmony modules

Object literals :

var newObject = {
  variableKey: variableValue,
  functionKey: function() {
    //…
  }
};

The modules Pattern:

Let's begin looking at an implementation of the Module pattern by created a module that is self-contained.

var testModule = (function() {
  var counter = 0;
  return {
    incrementCounter: function() {
      return ++counter;
    },
    resetCounter: function() {
      counter = 0;
    }
  };
})();

// Usage:
testModule.incrementCounter();
testModule.resetCounter();

3. The Revealing Module Pattern

One thing that the revealing module can do is avoiding repeat the name of the main object when we want to call one public method from another or access public variables.

var myRevealingModule = (function() {
  var privateVariable = 'not okay',
    publicVariable = 'okay';
  function privateFun() {
    return privateVariable;
  }

  function publicSetName(strName) {
    privateVariable = strName;
  }

  function publicGetName() {
    privateFun();
  }

  return {
    setName: publicSetName,
    message: publicVariable,
    getName: publicGetName
  };
})();

//Usage:

myRevealingModule.setName('Marvin King');

4. The Singleton Pattern

The Singleton pattern is thus known because it restricts instantiation of a class to single object. Singletons differ from static classes as we can delay their initialization. generally because they require some information that may not be available during initialization time. For code that is unaware of a previous reference to them, they do not provide a method for easy retrieval. Let's have a look of the structure of singleton:

var singletonPattern = (function() {
  var instance;
  function init() {
    // Singleton
    function privateMethod() {
      console.log('privateMethod');
    }
    var privateVariable = 'this is private variable';
    var privateRandomNumber = Math.random();
    return {
      publicMethod: function() {
        console.log('publicMethod');
      },
      publicProperty: 'this is public property',
      getRandomNumber: function() {
        return privateRandomNumber;
      }
    };
  }

  return {
    // Get the singleton instance if one exists
    // or create if it doesn't
    getInstance: function() {
      if (!instance) {
        instance = init();
      }
      return instance;
    }
  };
})();

// Usage:
var single = singletonPattern.getInstance();

5. The Observer Pattern

The observer is a design pattern in which an object maintains a list of objects depending on it observers, automatically notifying them of any changes to state.

  • Subject
    • Maintains a list of observers, facilities adding or removing observers
  • Observer
    • Provides an update interface for object that need to be notified of a subject’s change of state
  • ConcreteSubject
    • Broadcasts notifications to Observers on changes of state, stores the state of ConcreteObservers
  • ConcreteObserver
    • Stores a reference to the ConcreteSubject, implements an update interface for the observer to ensure state is consistent with subjects
function ObserverList() {
  this.observerList = [];
}

ObserverList.prototype.Add = function(obj) {
  return this.observerList.push(obj);
};

ObserverList.prototype.Empty = function() {
  this.observerList = [];
};

ObserverList.prototype.Count = function() {
  return this.observerList.length;
};

ObserverList.prototype.Get = function(index) {
  if (index > -1 && index < this.observerList.length) {
    return this.observerList[index];
  }
};

//...

When a subject needs to notify observers about something interesting happening, it broadcasts a notification to the observers ( including specific data related to the topic of the notification)

When we no longer wish for a particular observer the notified of changes by the subject it is registered with, the subject can remove it from the list of observers. In the future, I will talk more about the feature of how the observer can be used in JavaScript widely.

6. The Mediator Pattern

If it appears a system has too many direct relationships between components. it may be time to have a central point of the control that components communicate through instead. The mediator pattern promotes loose coupling by ensuring that instead of components referring to each other explicitly.

var mediator = (function() {
  var topics = {};
  var subscribe = function(topic, fn) {
    if (!topics[topic]) {
      topics[topic] = [];
    }
    topics[topic].push({ context: this, callback: fn });
    return this;
  };

  // publish/broadcast an event to the rest of the application
  var publish = function(topic) {
    var args;
    if (!topics[topic]) {
      return false;
    }
    args = Array.prototype.slice.call(arguments, 1);
    for (var i = 0, l = topics[topic].length; i < l; i++) {
      var subscription = topics[topic][i];
      subscription.callback.apply(subscription.content, args);
    }
    return this;
  };
  return {
    publish: publish,
    subscribe: subscribe,
    installTo: function(obj) {
      obj.subscribe = subscribe;
      obj.publish = publish;
    }
  };
})();

7. The Prototype Pattern

One of the benefits of using the Prototype pattern is that we've working with the prototype strengths JavaScript has to offer natively rather than attempting to imitate features of other languages. let's look at the pattern example.

var myCar = {
  name: 'bmw',
  drive: function() {
    console.log('I am driving!');
  },
  panic: function() {
    console.log('wait, how do you stop this thing?');
  }
};

//Usages:

var yourCar = Object.create(myCar);

console.log(yourCar.name); //'bmw'

8. The Factory Pattern

Factory can provide a generic interface for creating objects, where we can specify the type of factory object we wish to create. see the diagram below.

function Car(options) {
  this.doors = options.doors || 4;
  this.state = options.state || 'brand new';
  this.color = options.color || 'silver';
}

9. The Mixin Pattern

Mixins are classes that offer functionality that can be easily inherited by a sub-class or group of sub-classes for the purpose of the function reuse.

var Person = function(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
  this.gender = 'male';
};

var clark = new Person('Clark', 'kent');

var Superhero = function(firstName, lastName, powers) {
  Person.call(this.firstName, this.lastName);
  this.powers = powers;
};

SuperHero.prototype = Object.create(Person.prototype);
var superman = new Superhero('Clark', 'Kent', ['flight', 'heat-vision']);

console.log(superman); //output personal attributes as well as power

In this case, superhero is capable of overriding any inherited values with values specific to its object.

10. The Decorator Pattern

The Decorators are a structural design pattern that aim to promote code reuse. Similar to Mixins, they can be considered another viable alternative to object subclassing. Classically, Decorators offered that ability to add behavior to existing classes in a system dynamically. The idea was the decoration itself wasn't essential to the base functionality of the class. Let's checkout how decorator work in JavaScript

function MacBook() {
  this.cost = function() {
    return 997;
  };
  this.screenSize = function() {
    return 11.6;
  };
}

// Decorator 1

function Memory(macbook) {
  var v = macbook.cost();
  macbook.cost = function() {
    return v + 75;
  };
}

// Decorator 2

function Engraving(macbook) {
  var v = macbook.cost();
  macbook.cost = function() {
    return v + 200;
  };
}

// Decorator 3

function Insurance(macbook) {
  var v = macbook.cost();
  macbook.cost = function() {
    return v + 250;
  };
}

var mb = new MacBook();

Memory(mb);
Engraving(mb);
Insurance(mb);

mb.cost(); // 1522

All the patterns may not use to one project, and some projects may benefit from the decoupling benefits offered by the Observer pattern. That said, once we have a firm grasp-of design patterns and the specific problems they are best suited to. Thus, it becomes much easier to integrate into our application architecture.

Best Design Patterns for writing JavaScript Web applications

Best Design Patterns for writing JavaScript Web applications

Design patterns in JavaScript are reusable solutions applied to commonly occurring problems in writing JavaScript web applications. In this article, I will explore best and most popular JavaScript design patterns.

**Introduction

It is quite appropriate to refer JavaScript design patterns as templates to provide solutions to problems but not quite to say that these patterns can replace the developers.

Object constructors are used to create specific types of objects — both preparing the object for use and accepting arguments which a constructor can use to set the values of member properties and methods when the object is first created.

  1. Object Creation

2. Basic Constructors

function person(firstName,lastName){
  
  this.firstName = firstName;
  
  this.lastName = lastName;
  
  this.fullName = function(){
    return this.firstName + " " + this.lastName;
  }
  
}

var person1 = new person('Akash','Pal');
var person2 = new person('Black','Panther');
person1.fullName(); //"Akash Pal"
person2.fullName(); //"Black Panther"
person1 //{firstName: "Akash", lastName: "Pal", fullName: ƒ}
person2 //{firstName: "Black", lastName: "Panther", fullName: ƒ}

3. Constructor with prototypes.

In this article, I will explore seven best and most popular JavaScript design patterns, which of course most of them will fall under three categories namely; creation design patterns, structural design patterns and behavioral design patterns. A pattern is something like the following image; just to acquaint you into the context.

The Module pattern was originally defined as a way to provide both private and public encapsulation for classes in conventional software engineering.

In JavaScript, the Module pattern is used to further emulate the concept of classes in such a way that we’re able to include both public/private methods and variables inside a single object, thus shielding particular parts from the global scope. What this results in is a reduction in the likelihood of our function names conflicting with other functions defined in additional scripts on the page.

var personModule = (function(){
  
  var firstName;
  var lastName;
  
  return{
    setName(f,l){
      firstName = f;
      lastName = l;
    },
    getName(){
      return firstName + " " + lastName;
    }
  }
  
})();

personModule.setName('akash','pal')
personModule.getName() //"akash pal"

An updated pattern where we would simply define all of our functions and variables in the private scope and return an anonymous object with pointers to the private functionality we wished to reveal as public.

var personModule = (function(){
  
  var firstName;
  var lastName;
  
  function setName(f,l){
    firstName = f;
    lastName = l;
  }
  
  function getName(){
    return firstName + " " + lastName;
  }
  
  return{
    setName:setName,
    getName:getName
  }
  
})();

personModule.setName('akash','pal');
personModule.getName(); //"akash pal"

The Singleton pattern is thus known because it restricts instantiation of a class to a single object. Classically, the Singleton pattern can be implemented by creating a class with a method that creates a new instance of the class if one doesn’t exist. In the event of an instance already existing, it simply returns a reference to that object.

var singleton = (function(){

  var instance;
  
  function init(){
    
    var name;
    
    this.setName = function(name){
       this.name = name;
    }
    
    this.getName = function(){
      return this.name;
    }
    
    return{
      setName:setName,
      getName:getName
    }
      
  }
  
  function getInstance(){
    
    if(!instance){
      instance = init();
    }
    
    return instance;
  }
    
  return{
    getInstance:getInstance
  }  
  
})();


var one = singleton.getInstance();
var two = singleton.getInstance();

//the two instance are same
one == two //true

one.setName('Akash');
two.getName(); //"Akash"

The Observer is a design pattern where an object (known as a subject) maintains a list of objects depending on it (observers), automatically notifying them of any changes to state.

  • Subject: maintains a list of observers, facilitates adding or removing observers
  • Observer: provides an update interface for objects that need to be notified of a Subject’s changes of state
  • ConcreteSubject: broadcasts notifications to observers on changes of state, stores the state of ConcreteObservers
  • ConcreteObserver: stores a reference to the ConcreteSubject, implements an update interface for the Observer to ensure state is consistent with the Subject’s
Publish/Subscribe Pattern

The Observer pattern requires that the observer (or object) wishing to receive topic notifications must subscribe this interest to the object firing the event (the subject).

The Publish/Subscribe pattern however uses a topic/event channel which sits between the objects wishing to receive notifications (subscribers) and the object firing the event (the publisher). This event system allows code to define application specific events which can pass custom arguments containing values needed by the subscriber. The idea here is to avoid dependencies between the subscriber and publisher.

This differs from the Observer pattern as it allows any subscriber implementing an appropriate event handler to register for and receive topic notifications broadcast by the publisher.

A Mediator is an object that coordinates interactions (logic and behavior) between multiple objects. It makes decisions on when to call which objects, based on the actions (or inaction) of other objects and input.

We can think of the prototype pattern as being based on prototypal inheritance where we create objects which act as prototypes for other objects. The prototype object itself is effectively used as a blueprint for each object the constructor creates. If the prototype of the constructor function used contains a property called name for example (as per the code sample lower down), then each object created by that same constructor will also have this same property.

Real prototypical inheritance, as defined in the ECMAScript 5 standard, requires the use of Object.create

function person(firstName,lastName){
  
  this.firstName = firstName;
  
  this.lastName = lastName;
  
}

person.prototype.fullName = function(){
    return this.firstName + " " + this.lastName;
}

var person1 = new person('Akash','Pal');
var person2 = new person('Black','Panther');
person1 //{firstName: "Akash", lastName: "Pal"}
person2 //{firstName: "Black", lastName: "Panther"}
person1.fullName() //"Akash Pal"
person2.fullName() //"Black Panther"

The prototype pattern without directly using Object.create

The Command pattern aims to encapsulate method invocation, requests or operations into a single object and gives us the ability to both parameterize and pass method calls around that can be executed at our discretion. In addition, it enables us to decouple objects invoking the action from the objects which implement them, giving us a greater degree of overall flexibility in swapping out concrete classes(objects).

var name = {
  fName:'aaa',
  lName:'bbb',
  setName:function(fName,lName){
    this.fName = fName;
    this.lName = lName;
  },
  getName:function(){
     return this.fName + " " + this.lName;
  }
}

name.execute = function(key){
   var methodName = name[key];
   var functionParamsArray = [].splice.call(arguments,1);
   return methodName.apply(name,functionParamsArray);   
}

name.execute('setName','Akash','Pal');
console.log(name.execute('getName'));//Akash Pal

Facades are a structural pattern which can often be seen in JavaScript libraries like jQuery where, although an implementation may support methods with a wide range of behaviors, only a “facade” or limited abstraction of these methods is presented to the public for use.

Facades can also be integrated with other patterns such as the Module pattern.

The Factory pattern is another creational pattern concerned with the notion of creating objects. Where it differs from the other patterns in its category is that it doesn’t explicitly require us to use a constructor. Instead, a Factory can provide a generic interface for creating objects, where we can specify the type of factory object we wish to be created.

function Bike(options){
  this.wheels = 2;
  this.color = options.color;
}

function Car(options){
  this.wheels = 4;
  this.color = options.color;
}

function VehicleFactory(){}

VehicleFactory.prototype.createVehicle = function(options){
		
    switch(options.type){
    	case 'Bike': 
          this.vehicleClass = Bike;
      break;
      case 'Car': 
          this.vehicleClass = Car;
      break;
      default: 
          this.vehicleClass = Bike;
    }
    
    return new this.vehicleClass(options);
}

var vehicleFactory = new VehicleFactory();

var bike = vehicleFactory.createVehicle({
	type:'Bike',
  color:'black'
});

console.log(bike); //Bike {wheels: 2, color: "black"}

var car = vehicleFactory.createVehicle({
	type:'Car',
  color:'white'
});

console.log(car); //Car {wheels: 4, color: "white"}

Mixins are classes which offer functionality that can be easily inherited by a sub-class or group of sub-classes for the purpose of function re-use.

function Person(firstName,lastName){
  this.firstName = firstName; 
  this.lastName = lastName;
}

Person.prototype.fullName = function(){
    return this.firstName + " " + this.lastName;
}

function Superhero(firstName,lastName,powers){
  //super call
	Person.call(this,firstName,lastName);
  this.powers = powers;
}

Superhero.prototype = new Object(Person.prototype);

Superhero.prototype.showPowers = function(){
		return this.powers;
}

var superhero1 = new Superhero('Iron','Man',['Flying suit','Jarvis']);
console.log(superhero1.fullName() + '-' + superhero1.showPowers()); //Iron Man-Flying suit,Jarvis

var superhero2 = new Superhero('Captain','America',['strength','endurance','healing']);
console.log(superhero2.fullName() + '-' + superhero2.showPowers()); //Captain America-strength,endurance,healing

This articles includes examples derived from the below publication including my own inference of the patterns with the intention of simplifying the understanding of the patterns.

Conclusion

It is beneficial for JavaScript developers to use design patterns. Some major advantages of using design patterns include project maintainability and also cuts off unnecessary work on the development cycle. Even though JavaScript design patterns can provide solutions to complex problems, needless to say, rapid development and productivity, it is improper to conclude that these design patterns can replace the developers.

Thanks for reading, Hope this tutorial will surely help and you! Please share if you liked it!

Related Articles

The Comprehensive Guide to JavaScript Design Patterns

Top 10 JavaScript Design Patterns Every Developer Should Know

10 JavaScript Design Patterns You Should Know

7 best JavaScript Design Patterns You Should Know

Top 10 JavaScript Design Patterns Every Developer Should Know

Top 10 JavaScript Design Patterns Every Developer Should Know

In this article, you'll see top 10 JavaScript Design Patterns every Developer should know

1. The constructor Pattern

In classical object-oriented programming languages, a constructor is a special method used to initialize a newly created object once the memory has been allocated for it. In JavaScript almost everything is an object, we have most often interested in object constructors. Since object constructors are used to creating specific types of objects, for example, both preparing the object for use and accepting arguments a constructor can use to set the values of member properties and methods when the object is first created.

As we saw know JavaScript does not support the concept of classes, so inside a constructor, the keyword this references the new object that's being created revisiting object creation, a basic constructor may look as follows:

function Car(model, year, miles) {
 this.model = model;
 this.year = year;
 this.miles = miles;
}

// Usage:
var bmw = new Car('M4', '2019', '1000');

2. The module Pattern

Modules are an integral piece of any robust application's architecture and typically help in keeping the unit of code for a project cleanly separated and organized

There are several option for implementing modules. These include:

  • Object literal notation
  • The module Pattern
  • AMD modules
  • CommonJS module
  • ECMAScript Harmony modules

Object literals :

var newObject = {
 variableKey: variableValue,
 functionKey: function() {
   //…
 }
};

The modules Pattern:

Let's begin looking at an implementation of the Module pattern by created a module that is self-contained.

var testModule = (function() {
 var counter = 0;
 return {
   incrementCounter: function() {
     return ++counter;
   },
   resetCounter: function() {
     counter = 0;
   }
 };
})();

// Usage:
testModule.incrementCounter();
testModule.resetCounter();

3. The Revealing Module Pattern

One thing that the revealing module can do is avoiding repeat the name of the main object when we want to call one public method from another or access public variables.

var myRevealingModule = (function() {
 var privateVariable = 'not okay',
   publicVariable = 'okay';
 function privateFun() {
   return privateVariable;
 }

 function publicSetName(strName) {
   privateVariable = strName;
 }

 function publicGetName() {
   privateFun();
 }

 return {
   setName: publicSetName,
   message: publicVariable,
   getName: publicGetName
 };
})();

//Usage:

myRevealingModule.setName('Marvin King');

4. The Singleton Pattern

The Singleton pattern is thus known because it restricts instantiation of a class to single object. Singletons differ from static classes as we can delay their initialization. generally because they require some information that may not be available during initialization time. For code that is unaware of a previous reference to them, they do not provide a method for easy retrieval. Let's have a look of the structure of singleton:

var singletonPattern = (function() {
 var instance;
 function init() {
   // Singleton
   function privateMethod() {
     console.log('privateMethod');
   }
   var privateVariable = 'this is private variable';
   var privateRandomNumber = Math.random();
   return {
     publicMethod: function() {
       console.log('publicMethod');
     },
     publicProperty: 'this is public property',
     getRandomNumber: function() {
       return privateRandomNumber;
     }
   };
 }

 return {
   // Get the singleton instance if one exists
   // or create if it doesn't
   getInstance: function() {
     if (!instance) {
       instance = init();
     }
     return instance;
   }
 };
})();

// Usage:
var single = singletonPattern.getInstance();

5. The Observer Pattern

The observer is a design pattern in which an object maintains a list of objects depending on it observers, automatically notifying them of any changes to state.

  • Subject
  • Maintains a list of observers, facilities adding or removing observers
  • Observer
  • Provides an update interface for object that need to be notified of a subject’s change of state
  • ConcreteSubject
  • Broadcasts notifications to Observers on changes of state, stores the state of ConcreteObservers
  • ConcreteObserver
  • Stores a reference to the ConcreteSubject, implements an update interface for the observer to ensure state is consistent with subjects
function ObserverList() {
 this.observerList = [];
}

ObserverList.prototype.Add = function(obj) {
 return this.observerList.push(obj);
};

ObserverList.prototype.Empty = function() {
 this.observerList = [];
};

ObserverList.prototype.Count = function() {
 return this.observerList.length;
};

ObserverList.prototype.Get = function(index) {
 if (index > -1 && index < this.observerList.length) {
   return this.observerList[index];
 }
};

//...

When a subject needs to notify observers about something interesting happening, it broadcasts a notification to the observers ( including specific data related to the topic of the notification)

When we no longer wish for a particular observer the notified of changes by the subject it is registered with, the subject can remove it from the list of observers. In the future, I will talk more about the feature of how the observer can be used in JavaScript widely.

6. The Mediator Pattern

If it appears a system has too many direct relationships between components. it may be time to have a central point of the control that components communicate through instead. The mediator pattern promotes loose coupling by ensuring that instead of components referring to each other explicitly.

var mediator = (function() {
 var topics = {};
 var subscribe = function(topic, fn) {
   if (!topics[topic]) {
     topics[topic] = [];
   }
   topics[topic].push({ context: this, callback: fn });
   return this;
 };

 // publish/broadcast an event to the rest of the application
 var publish = function(topic) {
   var args;
   if (!topics[topic]) {
     return false;
   }
   args = Array.prototype.slice.call(arguments, 1);
   for (var i = 0, l = topics[topic].length; i < l; i++) {
     var subscription = topics[topic][i];
     subscription.callback.apply(subscription.content, args);
   }
   return this;
 };
 return {
   publish: publish,
   subscribe: subscribe,
   installTo: function(obj) {
     obj.subscribe = subscribe;
     obj.publish = publish;
   }
 };
})();

7. The Prototype Pattern

One of the benefits of using the Prototype pattern is that we've working with the prototype strengths JavaScript has to offer natively rather than attempting to imitate features of other languages. let's look at the pattern example.

var myCar = {
 name: 'bmw',
 drive: function() {
   console.log('I am driving!');
 },
 panic: function() {
   console.log('wait, how do you stop this thing?');
 }
};

//Usages:

var yourCar = Object.create(myCar);

console.log(yourCar.name); //'bmw'

8. The Factory Pattern

Factory can provide a generic interface for creating objects, where we can specify the type of factory object we wish to create. see the diagram below.

function Car(options) {
 this.doors = options.doors || 4;
 this.state = options.state || 'brand new';
 this.color = options.color || 'silver';
}
9. The Mixin Pattern

Mixins are classes that offer functionality that can be easily inherited by a sub-class or group of sub-classes for the purpose of the function reuse.

var Person = function(firstName, lastName) {
 this.firstName = firstName;
 this.lastName = lastName;
 this.gender = 'male';
};

var clark = new Person('Clark', 'kent');

var Superhero = function(firstName, lastName, powers) {
 Person.call(this.firstName, this.lastName);
 this.powers = powers;
};

SuperHero.prototype = Object.create(Person.prototype);
var superman = new Superhero('Clark', 'Kent', ['flight', 'heat-vision']);

console.log(superman); //output personal attributes as well as power

In this case, superhero is capable of overriding any inherited values with values specific to its object.

10. The Decorator Pattern

The Decorators are a structural design pattern that aim to promote code reuse. Similar to Mixins, they can be considered another viable alternative to object subclassing. Classically, Decorators offered that ability to add behavior to existing classes in a system dynamically. The idea was the decoration itself wasn't essential to the base functionality of the class. Let's checkout how decorator work in JavaScript

function MacBook() {
 this.cost = function() {
   return 997;
 };
 this.screenSize = function() {
   return 11.6;
 };
}

// Decorator 1

function Memory(macbook) {
 var v = macbook.cost();
 macbook.cost = function() {
   return v + 75;
 };
}

// Decorator 2

function Engraving(macbook) {
 var v = macbook.cost();
 macbook.cost = function() {
   return v + 200;
 };
}

// Decorator 3

function Insurance(macbook) {
 var v = macbook.cost();
 macbook.cost = function() {
   return v + 250;
 };
}

var mb = new MacBook();

Memory(mb);
Engraving(mb);
Insurance(mb);

mb.cost(); // 1522

All the patterns may not use to one project, and some projects may benefit from the decoupling benefits offered by the Observer pattern. That said, once we have a firm grasp-of design patterns and the specific problems they are best suited to. Thus, it becomes much easier to integrate into our application architecture.

Thanks for reading

If you liked this post, please do share/like it with all of your programming buddies!

Follow us on Facebook | Twitter

Further reading about JavaScript

The Complete JavaScript Course 2019: Build Real Projects!

Vue JS 2 - The Complete Guide (incl. Vue Router & Vuex)

JavaScript Bootcamp - Build Real World Applications

The Web Developer Bootcamp

JavaScript Programming Tutorial - Full JavaScript Course for Beginners

New ES2019 Features Every JavaScript Developer Should Know

Best JavaScript Frameworks, Libraries and Tools to Use in 2019

React vs Angular vs Vue.js by Example

Microfrontends — Connecting JavaScript frameworks together (React, Angular, Vue etc)

Creating Web Animations with Anime.js

Ember.js vs Vue.js - Which is JavaScript Framework Works Better for You

Do we still need JavaScript frameworks?