
Design patterns are reusable solutions to commonly occurring problems in software design. They fall into 3 categories:
ποΈ Creational Patterns
How objects are created
- 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.
- 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.
- 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
- 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
- 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.
- 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
United States
NORTH AMERICA
Related News
What Does "Building in Public" Actually Mean in 2026?
20h ago
The Agentic Headless Backend: What Vibe Coders Still Need After the UI Is Done
20h ago
Why Iβm Still Learning to Code Even With AI
22h ago
I gave Claude a persistent memory for $0/month using Cloudflare
1d ago
NYT: 'Meta's Embrace of AI Is Making Its Employees Miserable'
1d ago
