Design Patterns in JavaScript

Girma Nigusse
12 min readJun 21, 2021

1. Creational Patterns

Creational patterns are designed for class instantiation and object creation to increase flexibility and reuse of existing code.

  • builder pattern
  • factory pattern

Builder Pattern

Builder pattern separate the complexities of the creation logic from the final representation.

Problem

Imagine a complex object that requires laborious, step-by-step initialization of many fields and nested objects. Such initialization code is usually buried inside a monstrous constructor with lots of parameters. Or even worse: scattered all over the client code. … Refactoring Guru

Solution

A builder pattern is a design pattern that lets us extract the object construction out of its own class (its representation) so that it can be used for multiple different representations. One advantage to using this pattern is that it lets us build objects with one operation on top of another where we don’t need to call all operations simultaneously, only the ones that are needed to produce a particular output. … Yash Sharma

Factory Pattern

When a function returns an object, we call it a factory function.

Problem

In class-based programming, the factory method pattern is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created. This is done by creating objects by calling a factory method — either specified in an interface and implemented by child classes, or implemented in a base class and optionally overridden by derived classes — rather than by calling a constructor. … Jar Gon

Solution

The Factory pattern can be especially useful when applied to the following situations: When our object or component setup involves a high level of complexity. When we need to easily generate different instances of objects depending on the environment we are in. When we’re working with many small objects or components that share the same properties. When composing objects with instances of other objects that need only satisfy an API contract (a.k.a., duck typing) to work. This is useful for decoupling. … Addy Osmani

2. Structural Patterns

Stractural patterns are designed with regard to a class’s structure and composition.

  • decorator pattern
  • facade pattern

Decorator Pattern

In its simplest form, a decorator is simply a way of wrapping one piece of code with another — literally “decorating” it. … Graham Cox

Problem

A common reason why developers use them is that their applications may contain features requiring a large quantity of distinct types of object. Imagine having to define hundreds of different object constructors for, say, a JavaScript game. … Addy Osmani

Solution

Decorators are a proposal for extending JavaScript classes which is widely adopted among developers in transpiler environments, with broad interest in standardization. TC39 has been iterating on decorators proposals for over five years. … Tc39 Proposal Decorators

Facade Pattern

The Façade pattern provides an interface which shields clients from complex functionality in one or more subsystems.

Problem

Imagine that you must make your code work with a broad set of objects that belong to a sophisticated library or framework. Ordinarily, you’d need to initialize all of those objects, keep track of dependencies, execute methods in the correct order, and so on. As a result, the business logic of your classes would become tightly coupled to the implementation details of 3rd-party classes, making it hard to comprehend and maintain. … Refactoring Guru

Solution

A facade is a class that provides a simple interface to a complex subsystem which contains lots of moving parts. A facade might provide limited functionality in comparison to working with the subsystem directly. However, it includes only those features that clients really care about. … Refactoring Guru

3. Behavioural Patterns

Behavioural patterns are designed depending on how one class communicates with others.

  • strategy pattern

Strategy Pattern

Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it. … Rob Dodson

Problem

A strategy pattern can be used in Javascript in many cases to replace a switch statement. It is especially helpful when the number of conditions is dynamic or very large. It allows the code for each condition to be independent and separately testable. … Rip Tutorial

Solution

Abstractly speaking, the Strategy pattern is relevant whenever you have a number of algorithms (or some combination of functions and inputs) that share some common behavior. Put another way, try using this pattern whenever you have a single Goal to accomplish with a number of Approaches. … Mike Pennisi

References

4. Builder Pattern

Builder pattern separate the complexities of the creation logic from the final representation.

Problem

Imagine a complex object that requires laborious, step-by-step initialization of many fields and nested objects. Such initialization code is usually buried inside a monstrous constructor with lots of parameters. Or even worse: scattered all over the client code. … Refactoring Guru

Imagine having a complex object that requires a large, systematic step-by-step initialization of abundant fields and nested objects. This can get buried inside a huge constructor with many parameters — or even scattered throughout your code. … Jsmanifest

The problem solved by the Builder pattern is easy to identify: this pattern should be used when it is necessary to use a constructor with a very long parameter list or when there is a long list of constructors with different parameters. … Carlos Caballero

The seemingly easiest solution to complex object is to extend the base car class and create a set of subclasses, each covering pieces of the parameters. But if you think about it, you will eventually face the issue of having to create new subclasses every time you come across new parameters, such as having tinted windows. And every time this happens, your hierarchy will grow even more. … Jsmanifest

You can use the builder pattern to avoid a common issue known as telescoping constructors, which is when you create smaller versions of a big constructor to reduce the amount of logic in the constructor. … Eslam Hefnawy

Solution

A builder pattern is a design pattern that lets us extract the object construction out of its own class (its representation) so that it can be used for multiple different representations. One advantage to using this pattern is that it lets us build objects with one operation on top of another where we don’t need to call all operations simultaneously, only the ones that are needed to produce a particular output. … Yash Sharma

Builder pattern separates the construction of complex object which involve computing multiple sequential operations from its representation. It produces different representations of an object using the same construct

Builders allow us to construct complex objects by only specifying the type and content of the object, shielding us from the process of creating or representing the object explicitly. … Addy Osmani

Director defines the order in which the construction steps are performed. Its purpose is the re-usability of specific configurations. The Director can be omitted in some implementations of this pattern. … Carlos Caballero

Directors are involved in defining methods ensuring that steps are executed in a specific order to build the commonly constructed objects. … Jsmanifest

The builder design pattern is self-explanatory. It creates objects but it really shines when there is a need to create multiple objects with some similarities. A builder avoids the necessity to create myriad subclasses from a base class or big constructors with a lot of conditional logic using method chaining. … Eslam Hefnawy

The parameters in the constructor are reduced and served in a much more readable way, and thus there is no need to pass in null for optional parameters to the constructor. … Itay Elgazar

Example

4.1. Class

Listing 1.1: builder/examples/class/index.js
Listing 1.2: builder/examples/class/test.js

4.2. Director

Listing 2.1: builder/examples/director/index.js
Listing 2.2: builder/examples/director/test.js

4.3. Function

Listing 3.1: builder/examples/function/index.js
Listing 3.2: builder/examples/function/test.js

4.4. Sequential

Listing 4.1: builder/examples/sequential/index.js
Listing 4.2: builder/examples/sequential/test.js

4.5. Typescript

Listing 5.1: builder/examples/typescript/index.ts
Listing 5.2: builder/examples/typescript/test.js

References

5. Decorator Pattern

In its simplest form, a decorator is simply a way of wrapping one piece of code with another — literally “decorating” it. … Graham Cox

Problem

A common reason why developers use them is that their applications may contain features requiring a large quantity of distinct types of object. Imagine having to define hundreds of different object constructors for, say, a JavaScript game. … Addy Osmani

Decorators provide flexibility to statically typed languages by allowing runtime changes as opposed to inheritance which takes place at compile time. JavaScript, however, is a dynamic language and the ability to extend an object at runtime is baked into the language itself. For this reason, the Decorator pattern is less relevant to JavaScript developers. In JavaScript the Extend and Mixin patterns subsume the Decorator pattern. … Do Factory

Whilst functional composition is already possible in JavaScript, it’s significantly more difficult — or even impossible — to apply the same techniques to other pieces of code (e.g. classes and class properties). … Graham Cox

Solution

Decorators are a proposal for extending JavaScript classes which is widely adopted among developers in transpiler environments, with broad interest in standardization. TC39 has been iterating on decorators proposals for over five years. … Tc39 Proposal Decorators

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 the ability to add behavior to existing classes in a system dynamically. The idea was that the decoration itself was not essential to the base functionality of the class; otherwise, it would be baked into the superclass itself. … Addy Osmani

Decorators are helpful for anything you want to transparently wrap with extra functionality. These include memoization, enforcing access control and authentication, instrumentation and timing functions, logging, rate-limiting, and the list goes on. … Addy Osmani Medium

In its simplest form, a decorator is simply a way of wrapping one piece of code with another — literally “decorating” it. This is a concept you might well have heard of previously as functional composition, or higher-order functions. … Graham Cox

The Decorator pattern extends (decorates) an object’s behavior dynamically. The ability to add new behavior at runtime is accomplished by a Decorator object which ‘wraps itself’ around the original object. Multiple decorators can add or override functionality to the original object. … Do Factory

With the introduction of Classes in TypeScript and ES6, there now exist certain scenarios that require additional features to support annotating or modifying classes and class members. Decorators provide a way to add both annotations and a meta-programming syntax for class declarations and members. Decorators are a stage 2 proposal for JavaScript and are available as an experimental feature of TypeScript. … Typescript

Example

5.1. Class

Listing 1.1: decorator/examples/class/index.js
Listing 1.2: decorator/examples/class/test.js

5.2. Function

Listing 2.1: decorator/examples/function/index.js
Listing 2.2: decorator/examples/function/test.js

5.3. Stage 2 Decorator

Listing 3.1: decorator/examples/stage.2.decorator/index.js
Listing 3.2: decorator/examples/stage.2.decorator/test.js

References

6. Facade Pattern

The Façade pattern provides an interface which shields clients from complex functionality in one or more subsystems.

Problem

Imagine that you must make your code work with a broad set of objects that belong to a sophisticated library or framework. Ordinarily, you’d need to initialize all of those objects, keep track of dependencies, execute methods in the correct order, and so on. As a result, the business logic of your classes would become tightly coupled to the implementation details of 3rd-party classes, making it hard to comprehend and maintain. … Refactoring Guru

Solution

A facade is a class that provides a simple interface to a complex subsystem which contains lots of moving parts. A facade might provide limited functionality in comparison to working with the subsystem directly. However, it includes only those features that clients really care about. … Refactoring Guru

A facade pattern provides a convenient higher-level interface to a larger body of code, hiding its true underlying complexity. … Addy Osmani

An area where Façades are used is in refactoring. Suppose you have a confusing or messy set of legacy objects that the client should not be concerned about. You can hide this code behind a Façade. … Do Factory

The Facade pattern both simplifies the interface of a class and it also decouples the class from the code that utilizes it. This gives us the ability to indirectly interact with subsystems in a way that can sometimes be less prone to error than accessing the subsystem directly. … Addy Osmani

The facade pattern is used to simplify a client’s interaction with a system. So it can be used when an application has a large and complex underlying code that the client does not need to see. … Educative Io

This depends on the environment you will be building the JavaScript in, each comes with it’s own set of tools to help you get the job done. If you are building a node application or module you will make use of node’s require() method and module.exports syntax to construct a facade. If you are building a web application or module using requirejs you will use define() and require() to build your facade, or if you are using es6 syntax you will be using the import and export statements. … Hendrik Volschenk

When building an application, we often face problems with external APIs. One has simple methods, other has them very complicated. Unifying them under one common interface is one of uses of the facade pattern. … Tomek Buszewski

Example

6.1. Class

Listing 1.1: facade/examples/class/index.js
Listing 1.2: facade/examples/class/test.js

6.2. Function

Listing 2.1: facade/examples/function/index.js
Listing 2.2: facade/examples/function/test.js

References

7. Factory Pattern

When a function returns an object, we call it a factory function.

Problem

In class-based programming, the factory method pattern is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created. This is done by creating objects by calling a factory method — either specified in an interface and implemented by child classes, or implemented in a base class and optionally overridden by derived classes — rather than by calling a constructor. … Jar Gon

There are many people who argue against using constructors at all. Their arguments boil down to the fact that if you aren’t careful, it can be easy to introduce bugs into your code when using constructors. … The Odin Project

Solution

The Factory pattern can be especially useful when applied to the following situations: When our object or component setup involves a high level of complexity. When we need to easily generate different instances of objects depending on the environment we are in. When we’re working with many small objects or components that share the same properties. When composing objects with instances of other objects that need only satisfy an API contract (a.k.a., duck typing) to work. This is useful for decoupling. … Addy Osmani

The factory function pattern is similar to constructors, but instead of using new to create an object, factory functions simply set up and return the new object when you call the function. … The Odin Project

The factory pattern wraps a constructor for different types of objects and returns instances of the objects via a simple API. It makes it easy to create different objects by exposing a simple API that return the specified object type. … Babs Craig

With a factory function, you can create as many user objects as you want. If you’re building a chat app, for instance, you can have a user object representing the current user, and also a lot of other user objects representing all the other users who are currently signed in and chatting. … Eric Elliott

Example

7.1. Class

Listing 1.1: factory/examples/class/index.js
Listing 1.2: factory/examples/class/test.js

7.2. Function

Listing 2.1: factory/examples/function/index.js
Listing 2.2: factory/examples/function/test.js

References

8. Strategy Pattern

Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it. … Rob Dodson

Problem

A strategy pattern can be used in Javascript in many cases to replace a switch statement. It is especially helpful when the number of conditions is dynamic or very large. It allows the code for each condition to be independent and separately testable. … Rip Tutorial

Do you ever find yourself writing a lengthy switch statements or if statements structured like a switch. Luckily there is the Strategy Pattern to help alleviate this complex, sometimes unintelligible code. You may have also noticed that this code can have quite a high Cyclomatic Complexity. … Los Techies

The problem with the if/else scenario is that it doesn’t scale. As our systems grow, we need a better way to inject new policies. We may have different strategies required for development, automated testing, and production environments. This is where the strategy pattern becomes so effective. … Jarrett Meyer

Solution

Abstractly speaking, the Strategy pattern is relevant whenever you have a number of algorithms (or some combination of functions and inputs) that share some common behavior. Put another way, try using this pattern whenever you have a single Goal to accomplish with a number of Approaches. … Mike Pennisi

Define a family of algorithms, encapsulate each one, and make them interchangeable. … Carlos Caballero

Strategy pattern uses the inversion of control technique for having decoupled code. Inversion of control is also known under the “Hollywood Principle”, which states “Don’t call us, we’ll call you”. In functional programming this is done a bit more naturally just by passing a callback. … Thomas Rubattel

The Strategy pattern encapsulates alternative algorithms (or strategies) for a particular task. It allows a method to be swapped out at runtime by any other method (strategy) without the client realizing it. Essentially, Strategy is a group of algorithms that are interchangeable. … Do Factory

The key idea is to create objects which represent various strategies. These objects form a pool of strategies from which the context object can choose from to vary its behavior as per its strategy. These objects(strategies) perform the same operation, have the same(single) job and compose the same interface strategy. … Chidume Nnamdi

This pattern seems to be very similar to Factory, Command and others. The main difference is that it is one to many pattern (one object can have many strategies). Also this pattern is used to define algorithms. … Bumbu

Example

8.1. Class

Listing 1.1: strategy/examples/class/index.js
Listing 1.2: strategy/examples/class/test.js

8.2. Currying

Listing 2.1: strategy/examples/currying/index.js
Listing 2.2: strategy/examples/currying/test.js

8.3. Function

Listing 3.1: strategy/examples/function/index.js
Listing 3.2: strategy/examples/function/test.js

8.4. Switch

Listing 4.1: strategy/examples/switch/index.js
Listing 4.2: strategy/examples/switch/test.js

8.5. Typescript

Listing 5.1: strategy/examples/typescript/index.ts
Listing 5.2: strategy/examples/typescript/test.ts

References

Disclaimer

The content published above is a snapshoot of a one time generated content from the orignal source. For more design patterns, up-to-date code example and content visit the live document at https://patternsandbox.github.io/javascript/

--

--