Mastering Real-Time Magic: The Observer Pattern

Mastering Real-Time Magic: The Observer Pattern

Oct 30 2023

What is the Observer Pattern ?

At its core, the Observer pattern establishes a one-to-many dependency between objects so that when one object (the subject) changes state, all its dependents (observers) are notified and updated automatically. This pattern is ideal for scenarios where an object's state change should trigger specific actions in other parts of the code.

Observer pattern schema


Real use case : Real-Time Dashboard

The Observer Class

1class Observer {
2  constructor() {
3    this.observers = [];
4  }
5
6  subscribe(callback) {
7    this.observers.push(callback);
8  }
9
10  unsubscribe(callback) {
11    this.observers = this.observers.filter(observer => observer !== callback);
12  }
13
14  notify(data) {
15    this.observers.forEach(observer => observer(data));
16  }
17}
18
19export default Observer;

In this implementation, we've defined an Observer class with methods to subscribe, unsubscribe, and notify observers.

Integrating the Observer Pattern

Now, let's use the Observer pattern to create a real-time dashboard with three data sources: stock prices, weather updates, and news alerts.

Stock Price

1const stockObserver = new Observer();
2
3function updateStockPrices(price) {
4  console.log(`Stock Price: $${price}`);
5}
6
7stockObserver.subscribe(updateStockPrices);
8
9// Simulate real-time updates
10setInterval(() => {
11  const newPrice = Math.random() * 100;
12  stockObserver.notify(newPrice);
13}, 2000);

Weather Updates

1const weatherObserver = new Observer();
2
3function updateWeather(weatherData) {
4  console.log(`Weather Update: ${weatherData}`);
5}
6
7weatherObserver.subscribe(updateWeather);
8
9// Simulate real-time updates
10setInterval(() => {
11  const newWeather = 'Sunny';
12  weatherObserver.notify(newWeather);
13}, 3000);

News Alerts

1const newsObserver = new Observer();
2
3function updateNews(news) {
4  console.log(`News Alert: ${news}`);
5}
6
7newsObserver.subscribe(updateNews);
8
9// Simulate real-time updates
10setInterval(() => {
11  const headlines = ['Breaking News 1', 'Breaking News 2', 'Breaking News 3'];
12  const randomNews = headlines[Math.floor(Math.random() * headlines.length)];
13  newsObserver.notify(randomNews);
14}, 5000);

By implementing the Observer pattern, we've achieved a real-time dashboard that updates stock prices, weather conditions, and news alerts as soon as new data is available.


Going further with a more complex example

1// Subject - Blog class
2class Blog {
3  constructor() {
4    this.subscribers = [];
5  }
6
7  // add a subscriber (observer)
8  subscribe(subscriber) {
9    this.subscribers.push(subscriber);
10  }
11
12  // remove a subscriber (observer)
13  unsubscribe(subscriberToRemove) {
14    this.subscribers = this.subscribers.filter(subscriber => subscriber !== subscriberToRemove);
15  }
16
17  // Notify when there is a new article
18  publishNewArticle(article) {
19    this.subscribers.forEach(subscriber => {
20      subscriber.notify(article);
21    });
22  }
23}
24
25// Observer - Subscriber class
26class Subscriber {
27  constructor(name) {
28    this.name = name;
29  }
30
31  // notification method
32  notify(article) {
33    console.log(`${this.name} got a notification : new article! - "${article}"`);
34  }
35}
36
37// Let's create a blog
38const myBlog = new Blog();
39
40// With three random users
41const subscriber1 = new Subscriber('Alice');
42const subscriber2 = new Subscriber('Bob');
43const subscriber3 = new Subscriber('Charlie');
44
45// The subscribers join to the blog
46myBlog.subscribe(subscriber1);
47myBlog.subscribe(subscriber2);
48myBlog.subscribe(subscriber3);
49
50// New article!
51myBlog.publishNewArticle('Les dernières tendances en programmation');
52
53// Result : Each subscriber got a notification
54
55// Unsubscribe a user
56myBlog.unsubscribe(subscriber2);
57
58// New article!
59myBlog.publishNewArticle('Guide de démarrage rapide en développement web');
60
61// Result : Only Alice AND Charlie got a notification.

Benefits of the Observer Pattern

1 - Real-Time Updates: The Observer pattern enables real-time updates across various parts of your application, providing a seamless and responsive user experience.

2 - Decoupled Code: Objects are loosely coupled, making it easy to add or remove observers without affecting other parts of the code.

3 - Customizable Reactions: Observers can define custom reactions to changes, allowing for flexibility and extensibility.


Conclusion

The Observer pattern is a valuable addition to your JavaScript toolkit, particularly when you need real-time updates and efficient communication between components. As demonstrated through our real-time dashboard example, it ensures that changes in one part of your application immediately affect other dependent parts, resulting in a more interactive and dynamic user experience.

My X

My portfolio

See more articles