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! π
Top comments (0)