Lab 09: Design Patterns
Overview
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
Summary
Pattern
Intent
Node.js Use Case
Last updated
