Let’s consider two objects in sight. One of the two objects for some reason, wants to know whenever the other object changes its state to get updated with every change.
One way is for that object to constantly ask its object of interest
if it has changed. This has to be done strenuously indefinitely. Hence there arises questions as to what would be the time interval between each ask? Would the other object’s update frequency be quick enough to cater to every modification that the object of interest
has gone through? Talk about scaling! What would happen if there are tons of other objects that need to be updated whenever the object of interest
has changed?
To avoid this absurdity, comes to the rescue, the observer design pattern!
A good idea would be for the object of interest
to take the responsibility of informing all its subjects
when it has changed. The essence of observer pattern is for the object of interest
to know its subscribers.
Thus, the objects register
with their object of interest.
And so the object of interest
here becomes the Publisher
and the objects that are notified when the Publisher
changes its state become the Subscribers/Observers.
This relationship between the Publisher
and the Subscribers
is what we call one to many dependency
among objects.
class Publisher {
constructor() {
this.state = null;
this.subscribers = [];
}add(subscriber) {
this.subscribers.push(subscriber);
}remove(subscriber) {
this.subscribers = this.subscribers.filter(sub => sub.name !== subscriber.name);
return this.subscribers;
}notify() {
for(let subscriber of this.subscribers) {
subscriber.update();
}
}changeState(state) {
this.state = state;
this.notify();
}getSubscribers() {
console.log(this.subscribers);
}
}class Subscriber {
constructor(name) {
this.name = name;
this.value = 0;
}update() {
this.value++;
console.log(this.name, 'has updated!', this.value);
}
}let pub = new Publisher();
let sub1 = new Subscriber('sub1');
let sub2 = new Subscriber('sub2');pub.add(sub1);
pub.add(sub2);
pub.remove(sub1);
pub.getSubscribers();
pub.changeState(1);