JavaScript Design Patterns
Design patterns in JavaScript solve recurring architecture problems. The language's flexibility enables multiple pattern implementations, and interviewers at senior level expect you to know and explain them.
// ── Module Pattern — private scope ───────────────────────────────
const UserStore = (() => {
const users = []; // private
return {
add: (user) => users.push(user),
get: (id) => users.find(u => u.id === id),
count: () => users.length,
};
})();
UserStore.add({id: 1, name: 'Rahul'});
console.log(UserStore.count()); // 1
console.log(UserStore.users); // undefined (private!)
// ── Observer (Pub/Sub) ────────────────────────────────────────────
class EventEmitter {
#events = {};
on(event, fn) {
(this.#events[event] ??= []).push(fn);
return () => this.off(event, fn); // unsubscribe fn
}
off(event, fn) {
this.#events[event] = this.#events[event]?.filter(f => f !== fn);
}
emit(event, ...args) {
this.#events[event]?.forEach(fn => fn(...args));
}
}
const bus = new EventEmitter();
const unsub = bus.on('userLogin', user => console.log(`${user.name} logged in`));
bus.emit('userLogin', {name: 'Rahul'}); // Rahul logged in
unsub(); // remove listener
// ── Proxy Pattern — intercept operations ─────────────────────────
const handler = {
get(target, prop) {
console.log(`Getting: ${prop}`);
return prop in target ? target[prop] : `${prop} not found`;
},
set(target, prop, value) {
if (prop === 'age' && typeof value !== 'number') {
throw new TypeError('age must be a number');
}
target[prop] = value;
return true;
}
};
const user = new Proxy({}, handler);
user.name = 'Rahul'; // sets ok
user.age = '25'; // TypeError: age must be a number
console.log(user.name); // Getting: name → 'Rahul'
// ── Strategy Pattern ──────────────────────────────────────────────
const sorters = {
bubble: (arr) => [...arr].sort((a,b) => a-b), // simplified
selection: (arr) => [...arr].sort((a,b) => a-b),
quick: (arr) => [...arr].sort((a,b) => a-b),
};
class Sorter {
setStrategy(name) { this.fn = sorters[name]; }
sort(arr) { return this.fn(arr); }
}
const s = new Sorter();
s.setStrategy('quick');
console.log(s.sort([3,1,4,1,5])); // [1,1,3,4,5]
Q: What is the difference between Observer and Pub/Sub?
In the Observer pattern, subjects and observers know about each other directly — observers register on the subject object. In Pub/Sub, publishers and subscribers are decoupled through an event bus/broker — publishers and subscribers never reference each other directly. Pub/Sub is more loosely coupled and suitable for cross-module communication.
Comments (0)
No comments yet. Be the first!
Leave a Comment