Welcome to Day 2 of my System Design Learning Series! Today, let's dive into Design Patterns, Observer Pattern.
📌 Use Case: Payment methods in e-commerce (Credit Card, PayPal, UPI).
🔹 Observer Design Pattern (Brief Overview)
The Observer Pattern establishes a one-to-many dependency between objects, so when one object (Observable) changes, all dependent objects (Observers) are notified.
📌 Use Case: Notification systems, event listeners, stock price updates.
🔍 Deep Dive: Observer Pattern – Walmart SDE Interview Question
❓ Implement a notify function to notify all subscribers when an event occurs.
💡 Solution:
1️⃣ Define an Observable (Publisher) that maintains a list of observers.
2️⃣ Implement attach, detach, and notify methods.
3️⃣ Product extends Observable : Whenever the product properties changes, all observers get updated.
4️⃣ The Observers (Subscribers) react when notified.
Here’s the Observer Pattern implementation for the problem using javascript:
class Observable {
constructor() {
this.observers = []; //maintaining list of observer
}
attach(observer) {
this.observers.push(observer); //adding new observer
}
detach(observer) {
this.observers = this.observers.filter(obs => obs !== observer);
//removing an observer in case of unsubscribing from notification service
}
notify(data) {
this.observers.forEach(observer => observer.update(data));
}
}
class Product extends Observable {
constructor(name, price) {
super();
this._name = name;
this._price = price;
}
// calling notify() whenever product value changes
set name(newName) {
this._name = newName;
this.notify(`Product name updated to: ${newName}`);
}
set price(newPrice) {
this._price = newPrice;
this.notify(`Price updated to: $${newPrice}`);
}
}
// creating an observer class to identify each observer
class Observer {
constructor(name) {
this.name = name;
}
update(message) {
console.log(`${this.name} received update: ${message}`);
}
}
// Usage Example:
const product = new Product("Laptop", 1000);
const observer1 = new Observer("Observer 1");
const observer2 = new Observer("Observer 2");
product.attach(observer1);
product.attach(observer2);
product.price = 1200; // Notifies observers
product.name = "Gaming Laptop"; // Notifies observers
observable.notify("New Event Occurred!"); // Both observers get notified
const product = new Product("Laptop", 1000);
const observer1 = new Observer("Observer 1");
const observer2 = new Observer("Observer 2");
product.attach(observer1);
product.attach(observer2);
product.price = 1200; // Notifies observers
product.name = "Gaming Laptop"; // Notifies observers
observable.notify("New Event Occurred!"); // Both observers get notified
🌟 Key Takeaways
✅ Loose Coupling: The observable and observers interact with minimal dependency.
✅ Flexibility: New observers can be added/removed dynamically.
✅ Real-World Use Cases: Notification services, stock market updates, event-driven systems.
What’s your take on the Observer Pattern? Have you encountered it in real-world scenarios? Let’s discuss in the comments! 🚀