Observer pattern in JS
Bài đăng này đã không được cập nhật trong 4 năm
Implementation
The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. -wikipedia
Basically, if you've ever worked with PubSub
, it's the same thing. It's one of the 23 pattherns defined in Gang of four
pattern book.
And it's used when, You need to maintain a one to many relation between objects.
Benefits:
- It supports the principle of loose coupling between objects that interact with each other
- It allows sending data to other objects effectively without any change in the Subject or Observer classes
- Observers can be added/removed at any point in time
- Learning Python Design Patterns - O'Reilly
Let us create the Subscriber first. From the definition we realize the Publisher should have a list of subscribers, So lets just do that.
function Publisher() {
this.subscribers = [];
}
Now, there should be an easy way to append a new subscriber to the subscribers
array. Let's add that too.
function Publisher() {
this.subscribers = [];
this.subscribe = (subscriber) => {
this.subscribers.push(subscriber)
}
}
The same way, subscribers should be able to unsubscribe easily.
this.unsubscribe = (unsubscriber) => {
this.subscribers = this.subscribers.filter(subscriber => {
if(subscriber !== unsubscriber) {
return subscriber;
}
})
}
And, finally, the publisher should be able to publish.
this.publish = () => {
this.subscribers.forEach(sub => sub.call())
}
So, the final code should look like
function Publisher() {
this.subscribers = [];
this.subscribe = (subscriber) => {
this.subscribers.push(subscriber)
}
this.unsubscribe = (unsubscriber) => {
this.subscribers = this.subscribers.filter(subscriber => {
if(subscriber !== unsubscriber) {
return subscriber;
}
})
}
this.publish = () => {
this.subscribers.forEach(sub => sub.call())
}
}
In short, each of the publisher
object will have it's own list of subscribers
, on which it can append or remove subscribers easily, and when the publish
method is invoked, each of the subscribers should be notified.
Now, let's create our subscribers. For brevity, we'll be using console.log
instead of actual api calls
const subscriberOne = () => {
console.log("calling subscriber one")
}
const subscriberTwo = () => {
console.log("calling subscriber two")
}
And Voila!. we're done. Now let's put it on test
p = new Publisher();
// subscrbe
p.subscribe(subscriberOne);
p.subscribe(subscriberTwo);
// unsubscribe
p.unsubscribe(subscriberTwo);
p.publish()
=> "calling subscriber one"
Live code
You can find the implementation here, modify it as you want and play.
https://repl.it/@SSalekin/ObserverPatternJs
Useful resources
Medium article 'The Observer Pattern' by Steven Levia
This excellent youtube video
All rights reserved