Mark As Completed Discussion

Observer

The Observer pattern helps objects learn about changes to the state of other objects. It does so by establishing a one-to-many dependency between objects. It's used extensively for event management.

You use the pattern when you have a critical object ("the subject"), a group of objects that depend on it ("observers"), and you need to make sure that observers are notified of any changes to the subject -- typically by calling one of their methods. Following this pattern helps circulate updates between objects without unnecessarily coupling them, and makes adding new observers easy.

Have you ever visited a website of a product that was yet to launch? Have you subscribed to receive an e-mail as soon as the product becomes publicly available? If you have, you acted as an observer, and the product acted as the subject.

Here's an example where a carsharing pool is the subject and implements the IObservable interface from C#'s Base Class Library, and a driver who uses the carsharing service is an observer and implements the IObserver interface:

1class SharedCar
2{
3    constructor(model) { this.model = model; }
4    getModel() { return this.model; }
5}
6
7class CarsharingCustomer
8{
9    constructor(name) { this.name = name; }
10    update(sharedCar) {
11        console.log(`Hey ${this.name}, a new car is available: ${sharedCar.getModel()}`);
12    }
13}
14
15class CarsharingPool
16{
17    constructor() {
18        this.availableCars = [];
19        this.observers = [];
20    }
21
22    addObserver(observer) {
23        this.observers.push(observer);
24    }
25
26    addCar(sharedCar)
27    {
28        this.availableCars.push(sharedCar);
29        this.observers.forEach(observer => observer.update(sharedCar));
30    }
31}

(The implementation above also uses a class called Unsubscriber that is omitted for brevity.)

At call site, the driver is subscribed to updates from the carsharing service, and gets a notification whenever a new shared car becomes available:

1const driver = new CarsharingCustomer("Louise Sawyer");
2
3const availableCars = new CarsharingPool();
4availableCars.subscribe(driver);
5availableCars.addCar(new SharedCar("Ford Thunderbird"));