2 min read

JavaScript Design Patterns

Design patterns are reusable solutions to common problems in software design. In JavaScript, they are crucial for writing maintainable, scalable, and secure code.

1. Module Pattern

The Module Pattern is used to emulate the concept of classes (before ES6) and to handle encapsulation. It keeps variables private and exposes only a public API.

const myModule = (function() {
  const privateVar = "I am private";

  function privateMethod() {
    console.log(privateVar);
  }

  return {
    publicMethod: function() {
      privateMethod();
    }
  };
})();

myModule.publicMethod(); // "I am private"
// myModule.privateMethod(); // Error

2. Singleton Pattern

The Singleton Pattern ensures that a class has only one instance and provides a global point of access to it.

const Singleton = (function() {
  let instance;

  function createInstance() {
    const object = new Object("I am the instance");
    return object;
  }

  return {
    getInstance: function() {
      if (!instance) {
        instance = createInstance();
      }
      return instance;
    }
  };
})();

const instance1 = Singleton.getInstance();
const instance2 = Singleton.getInstance();

console.log(instance1 === instance2); // true

3. Factory Pattern

The Factory Pattern is a creational pattern that provides an interface for creating objects but allows subclasses to alter the type of objects that will be created.

class Car {
  constructor(options) {
    this.doors = options.doors || 4;
    this.state = options.state || "brand new";
    this.color = options.color || "silver";
  }
}

class Truck {
  constructor(options) {
    this.state = options.state || "used";
    this.wheelSize = options.wheelSize || "large";
    this.color = options.color || "blue";
  }
}

class VehicleFactory {
  createVehicle(options) {
    if (options.vehicleType === "car") {
      return new Car(options);
    } else if (options.vehicleType === "truck") {
      return new Truck(options);
    }
  }
}

4. Observer Pattern

The Observer Pattern defines a subscription mechanism to notify multiple objects about any events that happen to the object they're observing.

class Subject {
  constructor() {
    this.observers = [];
  }

  subscribe(observer) {
    this.observers.push(observer);
  }

  unsubscribe(observer) {
    this.observers = this.observers.filter(obs => obs !== observer);
  }

  notify(data) {
    this.observers.forEach(observer => observer.update(data));
  }
}

class Observer {
  update(data) {
    console.log("Observer received:", data);
  }
}

programming/javascript/vanilla/javascript programming/design-patterns-index