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"));