DevPrep
  • Interview Prep
  • Projects
  • Resources
  • Pricing
  • About Us
Submit Question
DevPrep
  • Pricing
  • About Us
Submit Question
  1. Home
  2. Articles
  3. Frontend Engineering
  4. JavaScript Design Patterns: Factory, Singleton, and Observer
XLinkedInReddit
MediumFrontend Engineering

JavaScript Design Patterns: Factory, Singleton, and Observer

D
DevPrep Team
February 10, 2026·2 min read·0
Table of Contents
  • Factory Pattern
  • Singleton Pattern
  • Observer Pattern
  • When to Use What

Design patterns aren't academic theory — they're solutions to problems we face daily at Google. Here are the three most practical ones.

Factory Pattern

Creates objects without specifying the exact class. Perfect for creating different UI components based on configuration.

function createNotification(type, message) {
  const base = { message, timestamp: Date.now(), read: false };
  switch (type) {
    case "error": return { ...base, icon: "❌", priority: "high", color: "red" };
    case "warning": return { ...base, icon: "⚠️", priority: "medium", color: "yellow" };
    case "success": return { ...base, icon: "✅", priority: "low", color: "green" };
    default: return { ...base, icon: "ℹ️", priority: "low", color: "blue" };
  }
}

Singleton Pattern

Ensures a class has only one instance. In JavaScript, modules are already singletons — but sometimes you need explicit control.

class Database {
  static #instance = null;
  #connection = null;
  
  static getInstance() {
    if (!Database.#instance) {
      Database.#instance = new Database();
    }
    return Database.#instance;
  }
  
  connect(url) {
    if (!this.#connection) {
      this.#connection = createConnection(url);
    }
    return this.#connection;
  }
}

Observer Pattern

The foundation of event systems, React state, and pub/sub architectures.

class EventEmitter {
  #listeners = new Map();
  
  on(event, callback) {
    if (!this.#listeners.has(event)) this.#listeners.set(event, new Set());
    this.#listeners.get(event).add(callback);
    return () => this.#listeners.get(event).delete(callback); // unsubscribe
  }
  
  emit(event, ...args) {
    this.#listeners.get(event)?.forEach(cb => cb(...args));
  }
}

const bus = new EventEmitter();
const unsub = bus.on("userLoggedIn", (user) => console.log(user));
bus.emit("userLoggedIn", { name: "Rahul" });
unsub(); // cleanup

When to Use What

  • Factory: When object creation logic is complex or varies by type
  • Singleton: For shared resources (DB connections, loggers, config)
  • Observer: For decoupled communication between components

Related Articles

MediumFrontend Engineering

System Design #12: Design a Multi-Step Form Wizard

7 min read
MediumFrontend Engineering

Mastering Senior-Level JavaScript Interview Concepts

2 min read
MediumFrontend Engineering

System Design #9: Design a Collaborative Text Editor

9 min read

Comments (0)

Sign in to leave a comment.

No comments yet. Be the first to comment.

Table of Contents

  • Factory Pattern
  • Singleton Pattern
  • Observer Pattern
  • When to Use What

Series

View all Frontend Engineering articles →

Practice

  • JavaScript
  • DSA
  • Machine Coding
  • System Design

Resources

  • Learning Tracks
  • Articles
  • Roadmaps
  • Compare Concepts
  • Glossary
  • Developer Tools
  • All Questions

Company

  • About
  • Pricing

Legal

  • Privacy Policy
  • Terms of Service
DevPrep

© 2026 DevPrep. All rights reserved.