In the observer pattern, a subject maintains a collection of interested observers. Whenever there is a state change in which the observers are interested, they are notified so that each has a chance to update itself.
For example, the subject might be a live dataset which gets presented by different displays (the observers). Whenever the data changes, the displays get notified so they can update their presentation. In our initial use of this pattern, the subject is used to notify animated objects (the observers) of elapsed time so they can update themselves.
We’ll use class notation to define a Subject
class.
class Subject { // a subject maintains a set of registered observers constructor() { this.observers = new Set(); } // register observer obs with subject register(obs) { if (!this.observers.has(obs)) this.observers.add(obs); } // unregister observer obj from subject unregister(obs) { if (this.observers.has(obs)) this.observers.delete(obs); } // notify every registered observer of data notify(data) { this.observers.forEach(function (obs) {obs.update(data);}); } }
An observer is any object with an update property bound to a one-argument function. The argument is the data in which the observer is interested. Data may be a simple value or an object the observer can query for the information it needs to update itself.
To demonstrate the pattern, we define a possible observer class:
class Observer { constructor(name) { this.name = name; } update(data) { console.log(`${this.name} has just been notified of ${data}`); } }
In this example, an Observer
gets constructed with a string name. Whenever an observer receives an update message with the argument data, it prints a message that it has been notified of data. A sample transcript:
// construct a subject let subject = new Subject(); // construct two observers let earth = new Observer('Earth'); let saturn = new Observer('Saturn'); // register observer earth subject.register(earth); // notify the subject of morning subject.notify('morning'); // Earth has just been notified of morning // register observer Saturn subject.register(saturn); // notify the subject of afternoon subject.notify('afternoon'); // Earth has just been notified of afternoon // Saturn has just been notified of afternoon // deregister observer earth subject.unregister(earth); // notify the subject of night subject.notify('night'); // Saturn has just been notified of night