blog

  • Home
  • blog
  • JavaScript Design Patterns: The Observer Pattern

JavaScript Design Patterns: The Observer Pattern

In JavaScript, there is a problem that comes up often. You need a way to update parts of a page in response to certain events, with the data these provide. Say, for example, user input that you then project into one or many components. This leads into a lot of push-and-pull in the code to keep everything in sync.

This is where the observer design pattern can help — it enables one-to-many data binding between elements. This one-way data binding can be event driven. With this pattern, you can build reusable code that solves for your specific needs.

In this article, I’d like to explore the observer design pattern. It will help you solve a common problem you see in client-side scripting. That is one-to-many, one-way, and event-driven data binding. It is a problem that comes up often when you have many elements that must be in sync.

I’ll use ECMAScript 6 to illustrate the pattern. Yes, there will be classes, arrow functions, and constants. Feel free to explore these topics on your own if you are not already familiar. I’ll use parts of ES6 that introduce syntactic sugar only, so it is portable with ES5 if need be.

And I’ll use Test-Driven-Development (TDD) to work on the pattern. This way you have a way knowing how each component is useful.

The new language features in ES6 make for some succinct code. So, let’s get started.

The Event Observer

A high-level view of the pattern looks like this:

EventObserver
│ 
├── subscribe: adds new observable events
│ 
├── unsubscribe: removes observable events
|
└── broadcast: executes all events with bound data

After I flesh out the observer pattern I’ll add a word count that uses it. The word count component will take this observer and bring it all together.

To initialize the EventObserver do:

class EventObserver {
  constructor() {
    this.observers = [];
  }
}

Start with an empty list of observed events, and do this for every new instance. From now on, let’s add more methods inside EventObserver to flesh out the design pattern.

The Subscribe Method

To add new events do:

subscribe(fn) {
  this.observers.push(fn);
}

Grab the list of observed events and push a new item to the array. The list of events is a list of callback functions.

One way to test this method in plain JavaScript is as follows:

// Arrange
const observer = new EventObserver();
const fn = () => {};

// Act
observer.subscribe(fn);

// Assert
assert.strictEqual(observer.observers.length, 1);

I use Node assertions to test this component in Node. The exact same assertions exist as Chai assertions too.

Note the list of observed events consists of humble callbacks. We then check the length of the list and assert that the callback is on the list.

The Unsubscribe Method

To remove events do:

unsubscribe(fn) {
  this.observers = this.observers.filter((subscriber) => subscriber !== fn);
}

Continue reading %JavaScript Design Patterns: The Observer Pattern%

LEAVE A REPLY