Introduction
Design patterns are reusable solutions to common programming problems. They help structure your code, reduce bugs, improve readability, and scale apps better. Here are the most important patterns used in modern JavaScript.
1. Singleton Pattern
Ensures only one instance of an object exists.
class Settings {
constructor() {
if (Settings.instance) return Settings.instance;
this.theme = "dark";
Settings.instance = this;
}
}
const s1 = new Settings();
const s2 = new Settings();
console.log(s1 === s2); // true
2. Factory Pattern
Creates objects without specifying exact class.
function createCar(type) {
if (type === "subaru") return { brand:"Subaru", hp:125 };
if (type === "audi") return { brand:"Audi", hp:550 };
}
console.log(createCar("subaru"));
3. Module Pattern
Encapsulates private data.
const Counter = (function(){
let count = 0;
return {
inc(){ count++; },
get(){ return count; }
};
})();
Counter.inc();
console.log(Counter.get());
4. Observer Pattern
Listeners react to state changes.
class EventBus {
constructor(){ this.listeners = {}; }
on(event, fn){
(this.listeners[event] = this.listeners[event] || []).push(fn);
}
emit(event, data){
(this.listeners[event] || []).forEach(fn => fn(data));
}
}
const bus = new EventBus();
bus.on("login", user => console.log("User:", user));
bus.emit("login", "Kaloyan");
5. Strategy Pattern
Select algorithm at runtime.
const strategies = {
add:(a,b)=>a+b,
sub:(a,b)=>a-b
};
function calc(strategy, a, b){
return strategies[strategy](a,b);
}
console.log(calc("add", 5, 3));
6. Decorator Pattern
Enhance functions dynamically.
function log(fn){
return function(...args){
console.log("Called with", args);
return fn(...args);
}
}
function sum(a,b){ return a+b; }
const logged = log(sum);
logged(3,4);
7. Proxy Pattern
Intercept and control access to an object.
const user = { name:"Kaloyan", age:12 };
const proxy = new Proxy(user, {
get(target, prop){
console.log("Accessing:", prop);
return target[prop];
}
});
console.log(proxy.name);
8. Command Pattern
Encapsulate actions as objects.
class Command {
constructor(exec){ this.exec = exec; }
}
const helloCmd = new Command(() => console.log("Hello"));
helloCmd.exec();
9. MVC Pattern (Simple)
// Model
const model = { counter:0 };
// View
function render(){
document.body.innerHTML = "Count: " + model.counter;
}
// Controller
function inc(){
model.counter++;
render();
}
render();
10. Summary
- Singleton — one shared instance
- Factory — dynamic object creation
- Module — private/public separation
- Observer — event-driven architecture
- Strategy — interchangeable algorithms
- Decorator — extend functions
- Proxy — intercept object operations
- Command — action objects
- MVC — model, view, controller separation