Try   HackMD
tags: design pattern

Design Pattern - Observer

Observer pattern is the most common used pattern in web development. It can be almost commonly seen everywhere when using DOM's evenLisener

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

There are two key factors in such pattern:

  1. Subject class: subject changes will trigger the event sending the updated value to all the observers
  2. Observer class: Passively listen to the event sent from Subject object

Lets dive into the code:

Firstly, we can define the interfaces for Observer (subscriber) and Subject (Event sender)

interface Observer<T> {
  onChange(value: T): void;
}

interface Subject<T> {
  registerNewObserver(observer: Observer<T>): void;
  updateSubject(value: T): void;
  notifyObserver(): void;
  removeObserver(observer: Observer<T>): void;
}

Then we can create the PriceMonitor model by implimenting the Subject interface.

At the same time, we also create the PriceListener model by implimenting the Observer interface to listen to the price change event sent from PriceMonitor


class PriceMonitor implements Subject<number> {
  currentPrice = 0;

  private priceListeners: Observer<number>[] = [];

  registerNewObserver(observer: Observer<number>): void {
    this.priceListeners.push(observer);
  }
  updateSubject(value: number): void {
    this.currentPrice = value;
    this.notifyObserver();
  }
  notifyObserver(): void {
    for (let listener of this.priceListeners) {
      listener.onChange(this.currentPrice);
    }
  }
  removeObserver(observer: Observer<number>): void {
    if (this.priceListeners.includes(observer)) {
      let id = this.priceListeners.indexOf(observer);
      this.priceListeners.splice(id, 1);
    }
  }
}

class PriceListener implements Observer<number> {
  onChange(value: number): void {
    console.log(`Price updated to ${value}`);
  }
}

Finally, we instanciate the PriceMonitor and several PriceListener. We will see that when the price is updated, all the registered priceListeners will get the event.

let BtcPriceMonitor = new PriceMonitor();
let BtcPriceListener1 = new PriceListener();
let BtcPriceListener2 = new PriceListener();

BtcPriceMonitor.registerNewObserver(BtcPriceListener1);
BtcPriceMonitor.registerNewObserver(BtcPriceListener2);
BtcPriceMonitor.updateSubject(40000);

This is just a very simple priciple. You can also see the practicle example by checking [the vanilla-typescript dapp project] (https://github.com/happyeric77/vanillaTs_dapp_boilerplate.git)