DEV Community

Cover image for "Mastering JavaScript Design Patterns: A Comprehensive Handbook"
ishrat
ishrat

Posted on

"Mastering JavaScript Design Patterns: A Comprehensive Handbook"

JavaScript design patterns are reusable solutions to common problems that arise in software design. They provide a template for solving certain issues and can help developers create more maintainable and scalable code. Here's a comprehensive guide to some commonly used design patterns in JavaScript:

Singleton Pattern:

  • Ensures that a class has only one instance and provides a global point of access to it.
  • Useful for scenarios where a single instance controls actions, such as logging, or managing a pool of resources.
   var Singleton = (function () {
       var instance;

       function createInstance() {
           // Private constructor logic
           return {};
       }

       return {
           getInstance: function () {
               if (!instance) {
                   instance = createInstance();
               }
               return instance;
           }
       };
   })();
Enter fullscreen mode Exit fullscreen mode

Module Pattern:

  • Encapsulates and organizes code into a single, self-contained unit.
  • Uses closures to create private and public methods and variables.
   var Module = (function () {
       var privateVar = 10;

       function privateFunction() {
           console.log("Private Function");
       }

       return {
           publicVar: 20,
           publicFunction: function () {
               console.log("Public Function");
           }
       };
   })();
Enter fullscreen mode Exit fullscreen mode

Factory Pattern:

  • Defines an interface for creating objects, but leaves the choice of its type to the subclasses.
  • Useful when a class cannot anticipate the class of objects it must create.
   function CarFactory() {}

   CarFactory.prototype.createCar = function (model) {
       switch (model) {
           case 'Sedan':
               return new Sedan();
           case 'SUV':
               return new SUV();
           default:
               return new GenericCar();
       }
   };
Enter fullscreen mode Exit fullscreen mode

Observer Pattern:

  • Defines a one-to-many dependency between objects, so that when one object changes state, all its dependents are notified and updated automatically.
  • Commonly used in implementing distributed event handling systems.
   function ObserverList() {
       this.observers = [];
   }

   ObserverList.prototype.add = function (obj) {
       return this.observers.push(obj);
   };

   ObserverList.prototype.remove = function (obj) {
       this.observers = this.observers.filter(observer => observer !== obj);
   };

   ObserverList.prototype.notify = function (context) {
       this.observers.forEach(observer => observer.update(context));
   };
Enter fullscreen mode Exit fullscreen mode

Decorator Pattern:

  • Attaches additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.
  • Useful when you need to extend or enhance the behavior of objects in a flexible and reusable way.
   function Coffee() {
       this.cost = function () {
           return 5;
       };
   }

   function MilkDecorator(coffee) {
       this.cost = function () {
           return coffee.cost() + 2;
       };
   }
Enter fullscreen mode Exit fullscreen mode

Command Pattern:

  • Encapsulates a request as an object, thereby allowing for parameterization of clients with different requests, queuing of requests, and logging of the parameters.
  • Useful in decoupling the sender and receiver of a request.
   function Command(command) {
       this.execute = function () {
           console.log("Executing command: " + command);
       };
   }
Enter fullscreen mode Exit fullscreen mode

MVVM (Model-View-ViewModel) Pattern:

  • Separates an application into three main components: Model (data and business logic), View (UI and presentation), and ViewModel (mediator between Model and View).
  • Commonly used in the development of single-page applications.
   function Model(data) {
       this.data = data;
   }

   function ViewModel(model, view) {
       this.model = model;
       this.view = view;
   }
Enter fullscreen mode Exit fullscreen mode

Promise Pattern:

  • Represents a value that might be available now, or in the future, or never.
  • Provides a cleaner way to handle asynchronous operations and avoid callback hell.
   function asyncOperation() {
       return new Promise(function (resolve, reject) {
           // Asynchronous operation
           if (/* operation successful */) {
               resolve(result);
           } else {
               reject(error);
           }
       });
   }
Enter fullscreen mode Exit fullscreen mode

Facade Pattern:

  • Provides a simplified interface to a set of interfaces in a subsystem, making it easier to use.
  • Useful for hiding complex implementations and exposing only what is necessary.
   function Facade() {
       this.operation = function () {
           Subsystem1.operation1();
           Subsystem2.operation2();
       };
   }
Enter fullscreen mode Exit fullscreen mode

Strategy Pattern:

- Defines a family of algorithms, encapsulates each algorithm, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
- Useful when you want to define a family of algorithms, encapsulate each one, and make them interchangeable.
Enter fullscreen mode Exit fullscreen mode
```javascript
function Context(strategy) {
    this.strategy = strategy;
    this.executeStrategy = function () {
        this.strategy();
    };
}
```
Enter fullscreen mode Exit fullscreen mode

These patterns provide solutions to common problems in software design and help in creating maintainable, scalable, and modular code. It's important to choose the right pattern based on the specific requirements and constraints of your project. Additionally, JavaScript is a flexible language, and sometimes a combination of patterns may be the most suitable approach.

Top comments (0)