Lab 09: Design Patterns

Time: 30 minutes | Level: Practitioner | Docker: docker run -it --rm node:20-alpine sh

Overview

Implement classic design patterns in modern JavaScript: Observer/EventEmitter, Factory, Singleton, Strategy, Decorator, and Command patterns using Node.js built-ins.


Step 1: Observer / EventEmitter

const { EventEmitter } = require('events');

// Basic EventEmitter usage
class DataStore extends EventEmitter {
  #data = new Map();

  set(key, value) {
    const old = this.#data.get(key);
    this.#data.set(key, value);
    this.emit('change', { key, value, old });
    if (old === undefined) this.emit('add', { key, value });
    return this;
  }

  get(key) { return this.#data.get(key); }

  delete(key) {
    const value = this.#data.get(key);
    if (this.#data.delete(key)) this.emit('delete', { key, value });
    return this;
  }

  get size() { return this.#data.size; }
}

const store = new DataStore();
store.on('change', ({ key, value }) => console.log(`Changed: ${key} = ${value}`));
store.on('add', ({ key }) => console.log(`New key added: ${key}`));
store.on('delete', ({ key }) => console.log(`Deleted: ${key}`));

store.set('name', 'Alice'); // New key added: name / Changed: name = Alice
store.set('name', 'Bob');   // Changed: name = Bob
store.delete('name');        // Deleted: name

// Once listener
store.once('add', ({ key }) => console.log(`First add: ${key}`));
store.set('x', 1); // First add: x
store.set('y', 2); // (once listener already fired)

Step 2: Factory Pattern


Step 3: Singleton Pattern


Step 4: Strategy Pattern


Step 5: Decorator Pattern


Step 6: Command Pattern


Step 7: Combining Patterns


Step 8: Capstone — Observer + Singleton + Factory Demo

Run verification:

📸 Verified Output:


Summary

Pattern
Intent
Node.js Use Case

Observer

Notify many on state change

EventEmitter, pub/sub

Factory

Create without specifying exact class

Plugins, shapes, UI components

Singleton

Single global instance

Config, DB connection, EventBus

Strategy

Swap algorithms at runtime

Sorting, auth, payment

Decorator

Add behavior without changing class

Logging, caching, retry

Command

Encapsulate operations

Undo/redo, job queues, audit

Last updated