Creational Design Patterns in JavaScript
Tags: javascript, patterns, designpatterns, programming
Published: 2023-02-09 00:49:11


by [Chisom Kanu](https://blog.openreplay.com/authors/chisom-kanu)




Design patterns are commonly used by JavaScript web developers, sometimes without their knowledge when developing applications. Every developer aspires to create readable, maintainable, and reusable code. As applications grow, code organization becomes important, and design patterns are essential for overcoming this challenge. In this article, I'll explain what design patterns and their benefits are, and I'll also go through six creational design patterns and how they can be implemented in JavaScript.


## What are Design Patterns?

Reusable solutions to frequently occurring issues in software design are called design patterns. For developers collaborating on a project, they offer a means of describing and communicating designs in a common language. By separating all of the pointless repetition, JavaScript design patterns reduce the overall code base. [Design patterns](https://www.dofactory.com/javascript/design-patterns) in [JavaScript](https://www.w3schools.com/js/) can be useful while developing applications.



## Benefits of Design Patterns 


- Design patterns offer a collection of standardized and reusable solutions to typical design issues, which can reduce the amount of time and work required for development.

- They make the code base simpler to comprehend and edit, which increases a software project's ability to be maintained.

- Design patterns offer a flexible and adaptable foundation for the software design, which can make it simpler to add new features or functionalities to a project.

- Design patterns offer a flexible structure for the software's design, making it simpler to adapt to changing requirements or design objectives.

- Giving developers a common language for discussing and documenting design choices may promote communication and collaboration.

- A software project's overall quality can be raised using design patterns, which offer tested solutions to typical design issues.


## Types of Design Patterns

Different types of design patterns are commonly used in software development. They include:

### Creational design patterns

Design patterns known as ["creational"](https://blog.sessionstack.com/how-javascript-works-creational-structural-and-behavioural-design-patterns-4-best-practices-2e8beeba744c) are those that concentrate on the creation of items and try to do so in a way that is appropriate for the situation. Without identifying the precise class of object that will be created, these patterns seek to solve the challenge of constructing objects in a flexible and effective way.

Several creational design patterns are commonly used in software development. They include:


- [The factory design pattern](https://www.tutorialspoint.com/design_pattern/factory_pattern.htm)
- [The builder design pattern](https://codeburst.io/builder-pattern-in-javascript-e5b13e4e51af) 
- [The singleton design pattern](https://www.geeksforgeeks.org/singleton-design-pattern/)
- [The prototype design pattern](https://www.geeksforgeeks.org/prototype-design-pattern/)
- [The abstract factory design pattern](https://www.geeksforgeeks.org/abstract-factory-pattern/)
- [The object pool design pattern](https://www.geeksforgeeks.org/object-pool-design-pattern/)

### Structural design patterns

[Structural design patterns](https://www.javatpoint.com/structural-design-patterns) are a type of design pattern that focus on object composition, creating relationships between objects to form larger structures. When you need to connect objects to construct larger structures or break down huge objects into smaller pieces to create more adaptable and reusable solutions, they can be quite helpful. These patterns offer a means to put things together to create new functionality.

Structural design patterns include:

- [The adapter design pattern](https://www.geeksforgeeks.org/adapter-pattern/)
- [The decorator design pattern](https://www.tutorialspoint.com/design_pattern/decorator_pattern.htm)
- [The bridge design pattern](https://www.geeksforgeeks.org/bridge-design-pattern/)
- [The flyweight design pattern](https://www.geeksforgeeks.org/flyweight-design-pattern/?ref=lbp)
- [The composite design pattern](https://www.geeksforgeeks.org/composite-design-pattern/)


### Behavioral design patterns

[Behavioral design patterns](https://www.javatpoint.com/behavioral-design-patterns) are design patterns that focus on the communication between objects and how they operate together. These patterns aim to solve the problem of how objects can communicate and cooperate to achieve a specific goal and how the flow of control can be changed dynamically. They are used when you need to define communication and cooperation between objects.

Behavioral design patterns include:

- [The observer design pattern](https://www.javatpoint.com/observer-pattern)
- [The mediator design pattern](https://www.javatpoint.com/mediator-pattern)
- [The command design pattern](https://www.javatpoint.com/command-pattern)
- [The state design pattern](https://www.javatpoint.com/state-pattern)
- [The interpreter design pattern](https://www.javatpoint.com/interpreter-pattern)

### Concurrency design patterns

[Concurrency design patterns](https://en.wikipedia.org/wiki/Concurrency_pattern) are a type of design pattern that focus on the design of multi-threaded applications and how threads can communicate with watch other. These patterns aim to solve the issue of coordinating and synchronizing the action of multiple threads and managing shared resources in a thread-safe manner.

Some examples include:

- [The monitor design pattern](https://java-design-patterns.com/patterns/monitor/)
- [The producer-consumer design pattern](https://java-design-patterns.com/patterns/producer-consumer/) 
- [The reader-writer design pattern](https://java-design-patterns.com/patterns/reader-writer-lock/#explanation) 
- [The thread-pool design pattern](https://java-design-patterns.com/patterns/thread-pool/) 

### Architectural design patterns

[Architectural design pattern](https://medium.com/@hjkmines/javascript-design-and-architectural-patterns-cfa900c6fe41) is a design pattern that focuses on the overall structure of a software system and how its components are organized and arranged. These patterns solve the problem of designing a software system in a flexible and scalable manner and managing the complexity of large-scale systems.

Architectural design patterns include:

- [The model-view-controller pattern](https://www.edureka.co/blog/javascript-mvc/)
- [The event-bus design pattern](https://www.javaguides.net/2019/06/javascript-eventbus-example.html)
- [The serverless design pattern](https://medium.com/@eduardoromero/serverless-architectural-patterns-261d8743020) 
- [The microservice design pattern](https://www.edureka.co/blog/microservices-design-patterns)




<h2>Session Replay for Developers</h2> 
<p><em>
Uncover frustrations, understand bugs and fix slowdowns like never before with <strong><a href="https://github.com/openreplay/openreplay" target="_blank">OpenReplay</a></strong> — an open-source session replay suite for developers. It can be <strong>self-hosted</strong> in minutes, giving you complete control over your customer data
</em></p>
<img alt="OpenReplay" width="768" height="400" src="https://blog.openreplay.com/assets/overview_Z17Qdyg.png" class="astro-UXNKDZ4E" loading="lazy" decoding="async">
<em>Happy debugging! <a href="https://openreplay.com" target="_blank">Try using OpenReplay today.</a></em>






## Six Creational Design Patterns  in JavaScript 

Let's discuss the six creational design patterns and how they can be used in JavaScript.

### Constructor Pattern

The [constructor pattern](https://gomakethings.com/an-introduction-to-the-javascript-constructor-pattern/) belongs to the Creational design pattern category. The constructor design pattern in JavaScript is used to generate objects with particular properties and behaviors. It is a widely used pattern in [object-oriented programming](https://www.techtarget.com/searchapparchitecture/definition/object-oriented-programming-OOP) and offers a means to create objects that are initialized with specific values or states and may be changed through a range of parameters. A programmer develops a constructor function that specifies the properties and behavior of the object to apply the constructor design pattern in JavaScript. 

This constructor function is commonly defined within a class definition and is frequently given the class's name.

Here is an example of how to implement a constructor function in JavaScript:

```javascript
    function Car(make, model, year) {
      this.make = make;
      this.model = model;
      this.year = year;
    }
    
    // Create a new object using the Car constructor
    const myCar = new Car('Toyota', 'Camry', 2022);
    
    console.log(myCar.make); // Output: "Toyota"
    console.log(myCar.model); // Output: "Camry"
    console.log(myCar.year); // Output: 
    2022
```

The `Car` function is the constructor function in the example above. It takes three arguments: `make`, `model`, and `year`. The `this` keyword refers to the object being created. The object's properties are set to the values of the arguments passed to the constructor function.

To create a new object using the `Car` constructor, the `new` keyword is followed by a call to the `Car` function with the desired arguments. In this case, a new `Car` object is created with the make "Toyota", model "Camry", and year 2022.

The constructor design pattern is useful for creating objects with a similar structure and behavior. It allows you to define a blueprint for creating objects and then create multiple objects based on that blueprint.

These are the pros of this pattern:

- The use of constructor functions enables the production of numerous instances of an object, each with a different set of attribute values.

- Constructors can take arguments, allowing you more customization and flexibility when generating objects.

- The definition and setting of object properties and methods by constructors can be more effective than adding them to an object after it has already been constructed.

- Constructors are easily extendable and subclassable, enabling the construction of new objects with expanded capabilities.

- Since various functions and methods can be used to deal with objects, constructors offer a clear separation of concerns. They are in charge of constructing and initializing objects.

There are also some cons:

- It can be challenging for developers new to object-oriented programming to comprehend constructor functions.

- Constructors can be challenging to maintain since changes to one constructor could impact all instances of the object produced with it.

- Constructors can be inefficient since they need to be called each time an object is created, which can cause slower performance.

   

### Object Pool Pattern

The [object pool pattern](https://www.geeksforgeeks.org/object-pool-design-pattern/) is a software Creational design pattern that can be used in situations where the cost of initializing a class instance is high. It allows a program to reuse objects from a pool of objects rather than create new ones; this can improve the performance of a program by reducing the overhead of creating new objects and the time it takes to initialize them. 

The object pool pattern is often used when the objects are expensive to create and when you need many short-lived objects. 

How is it implemented in JavaScript? Here is an example of how you could implement an object pool in JavaScript:

```javascript
    class ObjectPool {
      constructor(createFn, resetFn) {
        this.createFn = createFn;
        this.resetFn = resetFn;
        this.pool = [];
      }
    
      acquire() {
        if (this.pool.length > 0) {
          return this.pool.pop();
        } else {
          return this.createFn();
        }
      }
    
      release(obj) {
        if (this.resetFn) {
          this.resetFn(obj);
        }
        this.pool.push(obj);
      }
    }
``` 

The `ObjectPool` class has two methods: `acquire` and `release`. The `acquire` method retrieves an object from the pool, or creates a new one using the `createFn` function if the pool is empty. The `release` method returns an object to the pool and calls the `resetFn` function (if provided) to reset the object's state.

Here is an example of how you might use the `ObjectPool` class:

```javascript
    const pool = new ObjectPool(
      () => new ExpensiveObject(),
      obj => obj.reset()
    );
    
    const obj1 = pool.acquire();
    const obj2 = pool.acquire();
    
    // Use the objects
    
    pool.release(obj1);
    pool.release(obj2);
```

In this example, we create an `ObjectPool` for `ExpensiveObject` instances and provide a function to reset the objects when they are returned to the pool. We then acquire two objects from the pool and use them. When we are finished with the objects, we return them to the pool using the `release` method.

The pros of object pool pattern are:


- Object pooling can help reduce the consumption of resources such as memory and network bandwidth by reusing objects rather than creating new ones.


- A thread-safe object pool can help reduce concurrency issues by providing a thread-safe way of obtaining and releasing objects.
    
- Object pooling can help improve the scalability of an application by reducing the demand on system resources.


- By reusing objects, object pooling can help reduce garbage collection overhead.

Some cons of object pool pattern are:


- Implementing an object pool can add complexity to an application, as it requires additional code to manage the pool of objects.


- An object pool limits the flexibility of an application, as it requires objects to be returned to the pool after use rather than being destroyed.


- In a multi-threaded environment, the object pool may require additional synchronization to ensure that objects are obtained and released in a thread-safe manner.

### Factory Pattern

The [factory design pattern](https://www.javatpoint.com/factory-method-design-pattern) is a creational design pattern that provides an interface for creating objects in a superclass but allows subclasses to alter the type of objects that will be created. Objects can be created using the factory design pattern without defining the precise class to be constructed. Instead, an object is created by a factory class, and the object type is decided upon at runtime based on the input the factory receives. Because it may produce objects of various types depending on the particular demands of the program at any given time, this gives the application's design additional flexibility.

How is it implemented in JavaScript? Here is an example of how the factory design pattern can be implemented in JavaScript:

```javascript
    // Superclass
    function Animal(name) {
      this.name = name;
    
      this.sayName = function() {
        console.log('My name is ' + this.name);
      };
    }
    
    // Subclass
    function Dog(name) {
      Animal.call(this, name);
    
      this.bark = function() {
        console.log('Woof, woof!');
      };
    }
    
    // Subclass
    function Cat(name) {
      Animal.call(this, name);
    
      this.meow = function() {
        console.log('Meow, meow!');
      };
    }
    
    // Factory
    function AnimalFactory() {}
    
    AnimalFactory.createAnimal = function(name, type) {
      switch(type) {
        case 'dog':
          return new Dog(name);
        case 'cat':
          return new Cat(name);
        default:
          throw new Error('Invalid animal type');
      }
    }
    
    // Usage
    var dog = AnimalFactory.createAnimal('Freya', 'dog');
    dog.sayName(); // My name is Freya
    dog.bark(); // Woof, woof!
    
    var cat = AnimalFactory.createAnimal('Lily', 'cat');
    cat.sayName(); // My name is Lily
    cat.meow(); // Meow, meow!
```

In this example, the `Animal` class is the superclass, and the `Dog` and `Cat` classes are subclasses that inherit from `Animal`. The `AnimalFactory` class is the factory class that has a `createAnimal` method for creating objects of different types, depending on the type parameter passed to the method. The `createAnimal` method uses a switch statement to determine which type of object to create and returns an instance of the appropriate class.

What are the pros of Factory Pattern?


- It encourages loose coupling between objects because the client code does not have to be aware of the specifics of how the objects it is creating are implemented. 


- Because the precise class to be built can be decided upon at runtime, it offers additional design flexibility for the program. 


- It can be used to build items needed in many configurations because the factory can produce objects in various configurations depending on the input.


And what cons are there?


- It can make the code more difficult to understand, as the implementation details of the objects being created are hidden behind the factory.


- It can make the code more difficult to test, as the factory and the objects being created by the factory may need to be mocked or stubbed to test the client code.


- It can lead to a proliferation of small classes, as a separate class may need to be created for each object type created by the factory.
    


### Singleton Pattern

The [singleton pattern](https://www.tutorialspoint.com/design_pattern/singleton_pattern.htm) is a design pattern that restricts the instantiation of a class to one "single" instance. This is useful when exactly one object is needed to coordinate actions across the system.

Here is an example of how the singleton design pattern can be implemented in JavaScript:

```javascript
    class Singleton {
      constructor() {
        // Check if an instance of the class already exists
        if (!Singleton.instance) {
          // If not, set the instance to this
          Singleton.instance = this;
        }
    
        // Return the instance of the class
        return Singleton.instance;
      }
    }
    
    // Create a new instance of the Singleton class
    const singleton = new Singleton();
    
    // Create another instance of the Singleton class
    const anotherSingleton = new Singleton();
    
    // Check if the two instances are the same object
    console.log(singleton === anotherSingleton); // Output: true
```

In the above example, the `Singleton` class has a constructor that checks if an instance of the class already exists. If not, it sets the instance to `this`, which is the current instance of the class. If an instance already exists, it simply returns the existing instance.
This allows you to ensure that there is only one instance of the `Singleton` class while providing a global access point to it through the `singleton` and `anotherSingleton` variables.

The following are the pros of this pattern:


- It ensures that a class has only one instance, which can be useful for managing resources or coordinating actions across the system.


- It can improve performance by reducing the need for multiple instances of a resource-intensive class.


-   It can reduce the complexity of the code by centralizing the management of a resource or process.

And these are the cons:


- It can make it harder to write unit tests, as the singleton may have side effects or depend on global state.


- It can lead to code that is difficult to understand or maintain, as the singleton pattern is often used to implement a global state or shared resources.


### Prototype Pattern 

In the [prototype design pattern](https://www.geeksforgeeks.org/prototype-design-pattern/), a prototype object is used as a template from which new objects are created. When you create a new object, you can specify which prototype to use as a blueprint, and the new object will have all the same properties and methods as the prototype. 
The prototype design pattern is useful for sharing methods and properties among objects in JavaScript and can help you avoid repeating code in your applications.

In JavaScript, you can use the `Object.create()` method to create a new object with a given prototype. For example:

```javascript
    const prototype = {
      sayHello: function() {
        console.log('Hello');
      }
    };
    
    const object1 = Object.create(prototype);
    object1.sayHello();  // Output: "Hello"
    
    const object2 = Object.create(prototype);
    object2.sayHello();  // Output: "Hello"
```    


In this example, `object1` and `object2` are created using the `prototype` object as a prototype. They both have a `sayHello()` method that can be called.

You can also use the prototype pattern to define your own custom object types in JavaScript. For example:

```javascript
    function Animal(name) {
      this.name = name;
    }
    
    Animal.prototype.sayName = function() {
      console.log(`My name is ${this.name}`);
    }
    
    const dog = new Animal('Freya');
    dog.sayName();  // Output: "My name is Freya"
    
    const cat = new Animal('Fluffy');
    cat.sayName();  // Output: "My name is Lily"
```    

In this example, the `Animal` function is a constructor for creating new `Animal` objects. The `sayName()` method is defined on the `Animal.prototype` object, so it's shared among all `Animal` objects. The `dog` and `cat` objects are created using the `Animal` constructor, and they both have access to the `sayName()` method.

These are some pros of this pattern:


- Makes it easy to create new objects based on a prototype, saving you time and effort.


    
- Allows you to define a standard set of methods and properties available to all objects created from a prototype.


- Can improve the performance of your application by reducing the amount of memory used to store duplicate copies of methods and properties.

Here are some cons of it:


- Can make your code more difficult to understand, especially for developers unfamiliar with the prototype pattern.


- Can make it harder to debug your code since the prototype chain can be complex and hard to follow.


- Can cause problems if you are not careful about how you use the prototype pattern, such as adding methods or properties to the prototype after you have already created objects based on it.



## Conclusion

In many ways, design patterns benefit developers. They remain constant throughout time and can be applied to standard and high-level applications. Most JavaScript developers frequently interact with design patterns without realizing it when building applications. This article covered five JavaScript design patterns and different types of design patterns.


[![newsletter](https://blog.openreplay.com/newsletter_Z1P0UIP.png)](https://newsletter.openreplay.com/)