Back to blog

Implementing the Observer Pattern in TypeScript: A Practical Guide

·3 min read·
TypescriptEngineering ConceptsDesign Patterns

The Observer pattern is a popular design pattern used to establish a one-to-many relationship between objects, where changes in one object trigger updates in other dependent objects. In this article, we will explore how to implement the Observer pattern in TypeScript, a statically-typed superset of JavaScript. By the end of this article, you'll have a solid understanding of how to leverage the power of the Observer pattern in your TypeScript projects.

Overview of the Observer Pattern

The Observer pattern involves two key components: the subject and the observers. The subject is the object that holds the state and notifies observers of any changes. Observers are objects that depend on the subject and are notified when the subject's state changes. This pattern promotes loose coupling between objects, allowing for easy extensibility and maintainability.

Implementing the Observer Pattern in TypeScript

To understand the implementation of the Observer pattern in TypeScript, let's consider a real-world example of an online marketplace where buyers are interested in being notified when a new product is added to the inventory.

// Define the Subject
class Inventory {
  private observers: Observer[] = [];
 
  public addObserver(observer: Observer): void {
    this.observers.push(observer);
  }
 
  public removeObserver(observer: Observer): void {
    const index = this.observers.indexOf(observer);
    if (index !== -1) {
      this.observers.splice(index, 1);
    }
  }
 
  public notifyObservers(product: string): void {
    for (const observer of this.observers) {
      observer.update(product);
    }
  }
}
 
// Define the Observer
interface Observer {
  update(product: string): void;
}
 
class Buyer implements Observer {
  constructor(private name: string) {}
 
  public update(product: string): void {
    console.log(`[${this.name}] New product added: ${product}`);
  }
}
 
// Usage
const inventory = new Inventory();
 
const john = new Buyer("John");
const emily = new Buyer("Emily");
 
inventory.addObserver(john);
inventory.addObserver(emily);
 
inventory.notifyObservers("iPhone 13");
 
inventory.removeObserver(john);
 
inventory.notifyObservers("MacBook Pro");

In this example, the Inventory class acts as the subject and maintains a list of subscribed observers. The addObserver method adds an observer to the list, while the removeObserver method removes an observer from the list. The notifyObservers method triggers the update method on each subscribed observer, passing the updated product as an argument.

The Buyer class implements the Observer interface, which requires the implementation of the update method. In this case, the update method simply logs a message indicating that a new product has been added.

The Observer pattern is a powerful tool for establishing communication between objects in a loosely coupled manner. By implementing the Observer pattern in TypeScript, you can enhance the modularity and maintainability of your codebase. In this article, we explored a practical example of using the Observer pattern in TypeScript, demonstrating how a subject notifies its observers when its state changes.

By understanding and leveraging the Observer pattern, you can design more flexible and scalable TypeScript applications. Experiment with this pattern in your projects and explore how it can be applied to various scenarios to improve code organization and maintainability. Happy coding!

Enjoyed this article?

Get weekly insights on software development, architecture patterns, and industry best practices.