Fetching latest headlines…
JavaScript Design Patterns
NORTH AMERICA
πŸ‡ΊπŸ‡Έ United Statesβ€’April 17, 2026

JavaScript Design Patterns

0 views0 likes0 comments
Originally published byDev.to

Design patterns are reusable solutions to commonly occurring problems in software design. They fall into 3 categories:

πŸ—οΈ Creational Patterns
How objects are created

  1. Singleton Ensures only one instance of a class exists throughout the app.
javascriptclass Database {
  constructor() {
    if (Database.instance) return Database.instance;
    Database.instance = this;
  }
}

const db1 = new Database();
const db2 = new Database();
console.log(db1 === db2); // true

Use when: Managing a shared resource like a DB connection or config object.

  1. Factory A function/class that creates objects without specifying the exact class.
javascriptfunction createUser(role) {
  if (role === "admin") return { role, permissions: ["read", "write", "delete"] };
  if (role === "guest") return { role, permissions: ["read"] };
}

const admin = createUser("admin");
const guest = createUser("guest");

Use when: You need to create different object types based on a condition.

  1. Builder Constructs complex objects step by step.
javascriptclass QueryBuilder {
  constructor() { this.query = "SELECT "; }
  select(fields) { this.query += fields; return this; }
  from(table) { this.query += ` FROM ${table}`; return this; }
  where(condition) { this.query += ` WHERE ${condition}`; return this; }
  build() { return this.query; }
}

const query = new QueryBuilder()
  .select("*")
  .from("users")
  .where("age > 18")
  .build();

Use when: Building complex objects like SQL queries, form configs, or request options.

πŸ”— Structural Patterns

How objects are composed/organized

  1. Module Encapsulates code into self-contained units with private and public parts.
javascriptconst CartModule = (() => {
  let items = []; // private

  return {
    add: (item) => items.push(item),
    getItems: () => [...items],
    total: () => items.reduce((sum, i) => sum + i.price, 0),
  };
})();

CartModule.add({ name: "Shoes", price: 50 });
console.log(CartModule.total()); // 50

Use when: You want to avoid polluting the global scope (very common in JS).

5.** Decorator**
Adds new behavior to an object without modifying the original.

javascriptfunction withLogging(fn) {
  return function (...args) {
    console.log(`Calling with`, args);
    return fn(...args);
  };
}

const add = (a, b) => a + b;
const loggedAdd = withLogging(add);
loggedAdd(2, 3); // logs: Calling with [2, 3] β†’ returns 5

Use when: Adding features like logging, caching, or auth checks to functions.

πŸ”” Behavioral Patterns

How objects communicate

  1. Observer One object (subject) notifies multiple subscribers when something changes.
javascriptclass EventEmitter {
  constructor() { this.listeners = {}; }
  on(event, fn) {
    (this.listeners[event] ??= []).push(fn);
  }
  emit(event, data) {
    this.listeners[event]?.forEach(fn => fn(data));
  }
}

const emitter = new EventEmitter();
emitter.on("login", (user) => console.log(`${user} logged in`));
emitter.emit("login", "Alice"); // Alice logged in

Use when: Building event systems, real-time updates, or state management.

  1. Strategy Defines a family of algorithms and makes them interchangeable at runtime.
javascriptconst sorter = {
  bubble: (arr) => { /* bubble sort logic */ },
  quick:  (arr) => { /* quick sort logic */  },
};

function sortData(data, strategy = "quick") {
  return sorter[strategy](data);
}

Use when: You need to switch between different implementations of the same behavior (sorting, payment methods, validation rules).

Quick Reference

Comments (0)

Sign in to join the discussion

Be the first to comment!