Top 10 JavaScript Patterns Every Developer Likes
Tags: javascript, programming, webdev, patterns
Published: 2019-07-23 04:24:57

### 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.

![](https://www.plantuml.com/plantuml/svg/0/Iyv9B2vM24WiIiqhKQZcKW0224Ule2Y_9B-aiY0LB9XMcfTSafcVvwYXoLNBnPKCrkQNMkwVb9MQNAAGMb6IcfU2Pb1UQZbK0AW9tH0GFnviHppGG000)

<!-- ```plantuml
class Parent {
    Parent.prototype
    functionA()
}

class NewObject extends Parent {
    new Parent()
    functionA()
    _proto_
}
``` -->

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:

```javascript
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 :

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

The modules Pattern:

![](https://www.plantuml.com/plantuml/svg/0/Iyv9B2vMyCrFASr9TSxFAoxDJIsgvb800eYONa5fKavciczgIKP-Yg669gPKG55-GMfHIQKXLoqNLpAISGgf5IMfUIdefYj0ZCTcBfg1G568S55cMM99Ai8Y944q0w22hY118w1WBHS0)

<!-- ```plantuml
class ModuleConsumer{
    Module.publicMethod1()
    Module.publicProperty1
}

class Module extends ModuleConsumer {
    publicMethod1()
    publicProperty1()

    privateProperty1
    privateMethod1()
    privateMEthod2()
}
``` -->

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

```javascript
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.

```javascript
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:

```javascript
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.

![](https://www.plantuml.com/plantuml/svg/0/2ovDoafDBb6mKd1CIT7mJofEBIfBBTBa2eQB1wNcvfUbOfNooo_9JAlaudBEpqikIYr9XSfOAHIN99Qa-gT1-PZoxgabmI0b6fe8pJ0BSEf6A0WjI85gnYQ6Pfk2hfq2BgD0SkYEAyQf5gWOnk52CXpX1hWi5m00)

<!-- ```plantuml
Subject : Add(Observer)
Subject : Remove(Observer)
Subject : Notify

ConcreteSubject: stateOfSubject
ConcreteSubject: GetState()

ConcreteObserver: stateOfSubject
ConcreteObserver: Update()

Observer: Update()

ConcreteSubject -> Subject
Subject -> Observer: Observer
ConcreteObserver -> ConcreteSubject:subject
ConcreteObserver -> Observer
``` -->

- 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

```javascript
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

![](https://www.plantuml.com/plantuml/svg/0/SyxFoKbDJ2zDjLB8JKt9J2p9B-9oXeaPOXCqmYPeZ4tG14cGonVAib98piyjoCzBpIlXGYZLjVF5j1r94AvTLzSEuH8aH-aIKcoCv5Y2YasGF86Y6000)

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.

```javascript
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.

```javascript
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.

![](https://www.plantuml.com/plantuml/svg/0/SovAJIp9Bx9AIqm6KfM-gIKP-IaQcbpEKF7yWjIYn9BC_3oW69TpVbvoKMf9gZCEJJ1TkdPeAk4w0uhoKqgJItJje0nq8n4wOGgu0000)

<!--
```plantuml
Creator:factoryMethod()
Creator:operation()

ConcreteCreator:factoryMethod()

Creator->ConcreteCreator
ConcreteProduct->Product
ConcreteCreator->ConcreteProduct

``` -->

```javascript
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.

```javascript
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.

![](https://www.plantuml.com/plantuml/svg/0/yqijzq_AIaqkiKehpKikoSpFCzJGjERomn0smYxiwEGCak3opQp8p3EqKa0n1LtG2A7K226AQeIk7TmIg4eC4Q0QY0mN0000)

<!-- ```plantuml
NewObject:function1();
NewObject:function2();
NewObject:functionABC();

Mixin1: function1();
Mixin1: function2();

Mixin2: functionABC();

Mixin1->NewObject
Mixin2->NewObject
Mixin1->Mixin2
``` -->

### 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

```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.