Commonly Used Design Patterns in JavaScript

Commonly Used Design Patterns in JavaScript

A look at the singleton, iterator, and factory patterns

Image for postPhoto by George Pagan III on Unsplash.

Design patterns enable us to organize a program?s code in a standard way.

The book Design Patterns: Elements of Reusable Object-Oriented Software was published in 1994 and came up with 23 design patterns that are used by object-oriented programs.

In this piece, we?ll look at some of the more commonly used design patterns in JavaScript programs, including the singleton, iterator, and factory patterns.

Singleton

Singleton is a pattern that is common in JavaScript. It?s a class that only creates one instance of an object.

In JavaScript, we have the object literal to define an object that isn?t an instance of a class. For example, we have:

const obj = { foo: 1}

We also have the class syntax, which does the same thing as constructor functions, where we can define a getInstance method to get an instance of a class.

To make a singleton class, we can write something like the following:

Since we assigned this to this.instance and return it in getInstance, we should always get the same reference.

We should get that foo1 === foo2 being true since they reference the same instance of the Foo class.

Singleton classes are useful for facade objects to hide the complexities of a program. State objects that are shared by different parts of a program also make singleton classes a good choice.

They also let us share data without creating global variables. The global scope isn?t polluted, so it?s a good choice for sharing data.

Iterator

The iterator pattern is a pattern where we create an iterator to sequentially access data in a container.

We need this pattern to traverse items in collections without exposing the underlying data structure. And we should also be able to traverse objects in an aggregate object without changing its interface.

In JavaScript, we can define iterable objects and generators to do this.

To define an iterable object, we can write:

As we can see, iterableObj hides the array that?s inside it from the outside. Also, we can change it to anything else we want and not have to worry about changing the code outside.

[Symbol.iterator] and generator functions have been available since ES6. Ever since then, we can define iterators easily.

We can also define generator functions that return generators. To do this, we can write the following:

It?s similar to iterableObj since they both use generators. The difference is that generatorFn is a generator function that returns generators. Generators are what we iterate through.

Image for postPhoto by Nahil Naseer on Unsplash.

Factory

The factory pattern centers around the factory function. It?s a function that returns objects without using the new keyword to construct an instance of a class or a constructor function.

We want to use the factory pattern to make code more readable since it lets us create functions that return new objects from more code.

It also lets us return objects without knowing the code that creates the object. We don?t have to worry about what class is instantiated to create the object or how it?s created otherwise.

In JavaScript, when a function returns an object without the new keyword, then it?s a factory function.

For example, we can create a simple factory function as follows:

const createFoo = () => ({ foo: 1});

The createFoo function always returns the { foo: 1 } object when it?s called. It always returns an object without the new keyword, so it?s a factory function and uses the factory pattern.

Factory functions are common in JavaScript. For example, browsers have the document.querySelector() method to get a DOM object given the CSS selector.

There are similar methods that return objects everywhere in JavaScript.

The singleton pattern creates a single instance of an object. In JavaScript, we can do this with object literals or a getInstance method of a class that always returns the same instance of a class.

It?s useful for sharing data and hiding the complexity of implementation.

The iterator pattern lets us traverse through collections of objects without knowing the implementation of it. Also, it lets us change the underlying data structure and logic without changing the interface.

JavaScript has iterators to do this in addition to generator functions.

Finally, the factory pattern is common in JavaScript. Any function that returns a new object without using the new keyword to instantiate it is a factory function.

It?s useful for hiding the complexities of creating objects from other developers. For example, we don?t have to worry about how document.querySelector() gets an element from the DOM. It just returns the first DOM element that matches the selector.

22