If you’ve been coding in JavaScript for a while, you might have heard about design patterns. But what are they?
Think of design patterns like recipes for solving common problems in programming. Just like a cookie recipe tells you how to mix ingredients to get a perfect cookie, design patterns tell you how to structure your code so it works well, is easy to read, and doesn’t break easily.
Here, we’ll look at four super important patterns: Singleton, Module, Factory, and Observer. Let’s dive in!
1. Singleton Pattern
Idea: Only allow one instance of something to exist.
Analogy: Imagine the principal of a school. There’s only one principal, and everyone talks to that same person if they need help.
Why use it? When you want one object to control something globally, like a game score manager, or a database connection.
JavaScript Example:
const GameManager = (function () {
let instance; // this will hold the single instance
function init() {
let score = 0;
return {
increaseScore: function () {
score++;
console.log(`Score: ${score}`);
},
resetScore: function () {
score = 0;
console.log(`Score reset`);
}
};
}
return {
getInstance: function () {
if (!instance) {
instance = init();
}
return instance;
}
};
})();
// Usage
const game1 = GameManager.getInstance();
game1.increaseScore(); // Score: 1
const game2 = GameManager.getInstance();
game2.increaseScore(); // Score: 2 (same instance!)
✅ Notice how game1
and game2
are the same instance.
2. Module Pattern
Idea: Keep code organized and hide some parts from the outside world.
Analogy: A backpack. You can keep some things inside (like a pencil case), but only let people see or use what you want them to.
Why use it? To encapsulate code, keeping it neat and preventing accidental changes from outside.
JavaScript Example:
const Calculator = (function () {
// Private functions
function add(a, b) {
return a + b;
}
function subtract(a, b) {
return a - b;
}
// Public API
return {
sum: add,
difference: subtract
};
})();
// Usage
console.log(Calculator.sum(5, 3)); // 8
console.log(Calculator.difference(5, 3)); // 2
✅ Here, add
and subtract
are hidden inside the module, but we can still use them through Calculator.sum
and Calculator.difference
.
3. Factory Pattern
Idea: Create objects without specifying the exact class/type.
Analogy: A toy factory. You say "make me a toy," and it gives you a toy depending on your choice like car, doll, or robot, without you building it yourself.
Why use it? When you need lots of similar objects but don’t want to manually create each one.
JavaScript Example:
class Dog {
speak() {
console.log("Woof!");
}
}
class Cat {
speak() {
console.log("Meow!");
}
}
class AnimalFactory {
static createAnimal(type) {
if (type === "dog") return new Dog();
if (type === "cat") return new Cat();
throw new Error("Unknown animal type");
}
}
// Usage
const myPet = AnimalFactory.createAnimal("dog");
myPet.speak(); // Woof!
const neighborPet = AnimalFactory.createAnimal("cat");
neighborPet.speak(); // Meow!
✅ You don’t need to know the details of Dog
or Cat
. The factory does the work.
4. Observer Pattern
Idea: Let objects subscribe to events and react when those events happen.
Analogy: Think of YouTube notifications. You subscribe to a channel, and whenever the creator uploads a new video, you get notified automatically.
Why use it? When one object changes and many others need to know about it.
JavaScript Example:
class Subject {
constructor() {
this.observers = [];
}
subscribe(observer) {
this.observers.push(observer);
}
unsubscribe(observer) {
this.observers = this.observers.filter(obs => obs !== observer);
}
notify(data) {
this.observers.forEach(observer => observer.update(data));
}
}
class Observer {
constructor(name) {
this.name = name;
}
update(data) {
console.log(`${this.name} received: ${data}`);
}
}
// Usage
const news = new Subject();
const alice = new Observer("Alice");
const bob = new Observer("Bob");
news.subscribe(alice);
news.subscribe(bob);
news.notify("New JavaScript tutorial!");
// Alice received: New JavaScript tutorial!
// Bob received: New JavaScript tutorial!
✅ Any observer subscribed to news
automatically gets updates.
Conclusion
Design patterns might sound fancy, but they’re really just smart ways to organize your code. Here’s a quick recap:
Pattern | Idea | Example Use Case |
---|---|---|
Singleton | Only one instance | Game manager, DB connection |
Module | Hide private stuff, expose public API | Calculator, Utilities |
Factory | Create objects without knowing details | Toy factory, Animal creator |
Observer | Notify objects of changes | Chat apps, YouTube subs |
Top comments (0)