10 JavaScript Design Patterns Every Developer Should Know

10-javascript-design-patterns-every-developer-should-know

Hey there, fellow developer! 👋 Have you ever felt like your JavaScript code could be cleaner, more organized, or just easier to manage? Well, you’re not alone! Writing maintainable and scalable JavaScript is an art, and design patterns are here to help. Today, let’s explore 10 essential JavaScript design patterns that will not only level up your coding skills but also make your codebase a joy to work with. Grab a coffee ☕ and let’s dive in!

1. Singleton Pattern ☝️

Imagine you have a coffee machine in your office, and everyone shares it. You don’t want multiple instances of the machine popping up—just one for everyone. That’s exactly what the Singleton pattern does in JavaScript. It ensures that a class has only one instance and provides a global point of access to it.

class Singleton {
  constructor() {
    if (!Singleton.instance) {
      Singleton.instance = this;
    }
    return Singleton.instance;
  }
}
const instance1 = new Singleton();
const instance2 = new Singleton();
console.log(instance1 === instance2); // true

2. Factory Pattern 🏭

Ever ordered a coffee at a café? You tell them what you want, and they prepare it without you worrying about the details. The Factory pattern follows this idea by creating objects without specifying the exact class of the object being created.

class CoffeeFactory {
  static createCoffee(type) {
    if (type === "Espresso") return new Espresso();
    if (type === "Latte") return new Latte();
    throw new Error("Unknown coffee type");
  }
}
const myCoffee = CoffeeFactory.createCoffee("Espresso");

3. Observer Pattern 👀

Ever signed up for YouTube notifications? When a new video is uploaded, all subscribers get notified. The Observer pattern allows objects (subscribers) to react to changes in another object (publisher).

class Subject {
  constructor() { this.observers = []; }
  subscribe(observer) { this.observers.push(observer); }
  unsubscribe(observer) { this.observers = this.observers.filter(o => o !== observer); }
  notify(data) { this.observers.forEach(observer => observer.update(data)); }
}

4. Module Pattern 📦

Do you love keeping your workspace tidy? The Module pattern helps keep your code organized by encapsulating functionality into reusable modules.

const Calculator = (function () {
  let result = 0;
  return {
    add: (num) => (result += num),
    getResult: () => result,
  };
})();
Calculator.add(5);
console.log(Calculator.getResult()); // 5

5. Prototype Pattern 🧬

Ever copied and modified an existing document? The Prototype pattern lets you create objects based on an existing one.

const car = { wheels: 4, drive: () => console.log("Vroom!") };
const myCar = Object.create(car);
console.log(myCar.wheels); // 4

6. Decorator Pattern 🎨

Imagine ordering a coffee and adding extra toppings like caramel or whipped cream. The Decorator pattern allows you to enhance the behavior of objects dynamically.

function Coffee() { this.cost = () => 5; }
function MilkDecorator(coffee) {
  const cost = coffee.cost();
  coffee.cost = () => cost + 2;
}
const myCoffee = new Coffee();
MilkDecorator(myCoffee);
console.log(myCoffee.cost()); // 7

7. Command Pattern 🎮

Like a remote control, the Command pattern encapsulates requests as objects, allowing users to execute, undo, or queue them.

class Command {
  constructor(execute, undo) {
    this.execute = execute;
    this.undo = undo;
  }
}
const turnOn = new Command(() => console.log("Light On"), () => console.log("Light Off"));
turnOn.execute(); // Light On
turnOn.undo(); // Light Off

8. Strategy Pattern 🧠

Want to switch between different ways of doing something dynamically? The Strategy pattern lets you swap out algorithms on the fly.

class PaymentStrategy {
  pay(amount) {}
}
class CreditCardPayment extends PaymentStrategy {
  pay(amount) { console.log(`Paid ${amount} with Credit Card`); }
}
class PayPalPayment extends PaymentStrategy {
  pay(amount) { console.log(`Paid ${amount} via PayPal`); }
}
const payment = new CreditCardPayment();
payment.pay(100);

9. Proxy Pattern 🛡️

Think of a proxy as a personal assistant. Instead of talking directly to a VIP, you go through their assistant. The Proxy pattern provides an object that controls access to another object.

class RealSubject {
  request() { console.log("Handling request..."); }
}
class Proxy {
  constructor(realSubject) { this.realSubject = realSubject; }
  request() {
    console.log("Checking access...");
    this.realSubject.request();
  }
}
const proxy = new Proxy(new RealSubject());
proxy.request();

10. Mediator Pattern 🗣️

Think of a group chat where a mediator (the chat app) manages communication between participants. The Mediator pattern helps reduce dependencies between objects.

class Mediator {
  sendMessage(user, message) { console.log(`${user} says: ${message}`); }
}
const chatMediator = new Mediator();
chatMediator.sendMessage("Alice", "Hello, world!");

Wrapping Up 🎁

These 10 JavaScript design patterns will help you write cleaner, more maintainable, and more efficient code. Each pattern solves a different problem, so try them out and see how they fit into your projects!

If you found this article helpful, don’t forget to star my GitHub repo 👉 GitHub and buy me a coffeeBuy Me a Coffee. Your support keeps me motivated to create more content! 💖

Happy coding! 🚀

Total
0
Shares
Leave a Reply

Your email address will not be published. Required fields are marked *

Previous Post
daily-javascript-challenge-#js-108:-calculate-factorial-with-tail-recursion

Daily JavaScript Challenge #JS-108: Calculate Factorial with Tail Recursion

Next Post
how-i-use-inbound-marketing-to-drive-60k-monthly-visitors-(without-paid-ads)

How I Use Inbound Marketing to Drive 60k Monthly Visitors (Without Paid Ads)

Related Posts