Design Patterns in JavaScript

In JavaScript, there are several important design and asynchronous programming patterns used to structure code, manage complexity, and handle concurrency efficiently. Here’s a concise overview of key patterns:

There are the code examples one by one:

  1. Callback Pattern
function fetchData(callback) {
  setTimeout(() => {
    const data = { id: 1, name: "Alice" };
    callback(data);
  }, 1000);
}

fetchData((result) => {
  console.log("Data received:", result);
});
  1. Promise Pattern
function fetchData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const data = { id: 2, name: "Bob" };
      resolve(data);
    }, 1000);
  });
}

fetchData()
  .then(result => {
    console.log("Data received:", result);
  })
  .catch(error => {
    console.error("Error:", error);
  });
  1. Async/Await Pattern
function fetchData() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({ id: 3, name: "Carol" });
    }, 1000);
  });
}

async function getData() {
  try {
    const result = await fetchData();
    console.log("Data received:", result);
  } catch (error) {
    console.error("Error:", error);
  }
}

getData();
  1. Singleton Pattern
const Singleton = (function () {
  let instance;

  function createInstance() {
    return { timestamp: new Date() };
  }

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

const obj1 = Singleton.getInstance();
const obj2 = Singleton.getInstance();

console.log(obj1 === obj2); // true
console.log(obj1.timestamp);
  1. Factory Pattern
function Car(type) {
  this.type = type;
}

function Truck(type) {
  this.type = type;
}

function VehicleFactory() {}

VehicleFactory.prototype.createVehicle = function (type) {
  if (type === "car") {
    return new Car(type);
  } else if (type === "truck") {
    return new Truck(type);
  }
};

const factory = new VehicleFactory();
const myCar = factory.createVehicle("car");
const myTruck = factory.createVehicle("truck");

console.log(myCar.type);   // car
console.log(myTruck.type); // truck
  1. MVC Pattern
// Model
const model = {
  data: "Hello MVC",
};

// View
function view(data) {
  console.log("View: " + data);
}

// Controller
function controller() {
  const data = model.data;
  view(data);
}

controller();
  1. Singleton Pattern is ideal for only one feature in the full codebase such as database configuration/connection
  2. Facade Pattern, such as a compiler
  3. Bridge Pattern, decouple abstraction from implementation so they can vary independently.
  4. Strategy Pattern, a family of algorithms (strategies), encapsulates each one, and makes them interchangeable.

Note Abstraction is about hiding the complex details of how something works and exposing only the necessary parts for using it. You interact with an interface or function or class without needing to know its inner workings. The implementation details are hidden (encapsulated), and you only use what’s relevant. In OOP, Abstraction often appears as abstract classes or interfaces that define what something can do, not how.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.