Observer Pattern

The observer pattern defines a one-to-many dependency between objects. When an object’s state changes, all dependent objects are notified and updated automatically. Observer mode belongs to behavioral mode, which focuses on the communication between objects, while observer mode is the communication between the observer and the observed.

The observer model is also known as the publish-subscribe model, or subscription-publish model, in which subscribers are linked to the subscription target and notified individually when the subscription target changes. For example, when you subscribe to a newspaper, a new newspaper will be delivered to you every day. As many people subscribe to the newspaper, the newspaper will issue as many newspapers as possible. The “one-to-many” relationship between the newspaper and its customers is described at the beginning of the article above.

Publish and subscribe (pub-sub Pattern)

There is no publish-subscribe pattern among the 24 basic design patterns. As mentioned above, it is just another name for the observer pattern.

But over time, it seems to have grown stronger and become a different design pattern, independent of the observer pattern.

In the current publish-subscribe model, a message sender called a publisher does not send messages directly to the subscriber, which means that the publisher and subscriber are unaware of each other’s existence. Between the publisher and the subscriber exists a third component, called a message broker or scheduling center or middleware, which maintains the link between the publisher and the subscriber, filtering all incoming messages from the publisher and distributing them to the subscriber accordingly.

For example, you follow A on Weibo, and many other people also follow A, so when A releases A dynamic, weibo will push this dynamic for you. A is the publisher, you are the subscriber, and Weibo is the dispatch center. There is no direct communication between you and A, which is all coordinated through Weibo (your attention, A’s release dynamics).

What is the difference between the observer model and the publish-subscribe model?

The implementation structure of the two patterns:

Observer mode: The Observer directly subscribes to the Subject, and when the Subject is activated, it fires events within the Observer.

Publish and subscribe model: Subscriber registers the event they want to Subscribe to the dispatch center. When Publisher publishes the event to the dispatch center, that is, when the event is triggered, The processing code registered with the dispatch center by the Fire Event subscriber.

Code examples for two modes :(hunter publish and subscribe task)

Observer mode:

    // There is a hunter guild, in which every hunter can publish and subscribe
    // They all have a subscription list to keep track of who subscribed to them
    // Define a hunter
    // Include the name, level, and subscription list
    function Hunter(name, level){
        this.name = name
        this.level = level
        this.list = []
    }
    Hunter.prototype.publish = function (money){
        console.log(this.level + 'hunter' + this.name + 'Ask for help')
        this.list.forEach(function(item, index){
            item(money)
        })
    }
    Hunter.prototype.subscribe = function (targrt, fn){
        console.log(this.level + 'hunter' + this.name + 'Subscribed' + targrt.name)
        targrt.list.push(fn)
    }
    
    // Several hunters came to the hunter's guild
    let hunterMing = new Hunter('Ming'.'gold')
    let hunterJin = new Hunter('jin'.'silver')
    let hunterZhang = new Hunter('zhang'.'gold')
    let hunterPeter = new Hunter('Peter'.'bronze')
    
    //Peter is in a lower rank and may need help, so Xiao Ming, Jin and Zhang subscribe to Peter
    hunterMing.subscribe(hunterPeter, function(money){
        console.log('Xiao Ming said:' + (money > 200 ? ' ' : 'I'm busy right now. I can't.') + 'Give a hand')
    })
    hunterJin.subscribe(hunterPeter, function(){
        console.log('Kim says: Help')
    })
    hunterZhang.subscribe(hunterPeter, function(){
        console.log('Xiao Zhang said: Give help')})//Peter is in trouble
    hunterPeter.publish(198)
    
    // Hunters (observers) associate hunters (target objects) they are interested in, such as Peter, and automatically notify them (observers) when Peter is in trouble
Copy the code

Publish and subscribe model:

    // Define a hunter guild
    // The main features include topics such as subscribe and publish
    let HunterUnion = {
        type: 'hunt'.topics: Object.create(null),
        subscribe: function (topic, fn){
            if(!this.topics[topic]){
                  this.topics[topic] = [];  
            }
            this.topics[topic].push(fn);
        },
        publish: function (topic, money){
            if(!this.topics[topic])
                  return;
            for(let fn of this.topics[topic]){
                fn(money)
            }
        }
    }
    
    // Define a hunter
    // Include name, level
    function Hunter(name, level){
        this.name = name
        this.level = level
    }
    // Hunters can publish quests in the hunter guild
    Hunter.prototype.subscribe = function (topic, fn){
        console.log(this.level + 'hunter' + this.name + 'Subscribed to the hunt' + topic + 'Task')
        HunterUnion.subscribe(topic, fn)
    }
    Hunter.prototype.publish = function (topic, money){
        console.log(this.level + 'hunter' + this.name + 'Released the hunt' + topic + 'Task')
        HunterUnion.publish(topic, money)
    }
    
    // Several hunters came to the hunter's guild
    let hunterMing = new Hunter('Ming'.'gold')
    let hunterJin = new Hunter('jin'.'silver')
    let hunterZhang = new Hunter('zhang'.'gold')
    let hunterPeter = new Hunter('Peter'.'bronze')
    
    Xiao Ming, Xiao Jin and Xiao Zhang have subscribed to hunt Tiger respectively
    hunterMing.subscribe('tiger'.function(money){
        console.log('Xiao Ming said:' + (money > 200 ? ' ' : 'no') + 'Fetch task')
    })
    hunterJin.subscribe('tiger'.function(money){
        console.log('Kim says: Pick up the task')
    })
    hunterZhang.subscribe('tiger'.function(money){
        console.log('Xiao Zhang said: Pick up the task')})//Peter subscribed to hunt sheep
    hunterPeter.subscribe('sheep'.function(money){
        console.log('Peter says: Pick up task ')})//Peter announces the quest to hunt Tiger
    hunterPeter.publish('tiger'.198)
    
    // Hunters publish (publisher) or subscribe (observer/subscriber) quests are linked through hunters guild (dispatch center), they do not communicate directly.
Copy the code

The biggest difference between the observer mode and the publish-subscribe mode is that the publish-subscribe mode has an event scheduling center.

The observer mode is scheduled by the specific target, and each subscribed target needs to have observer processing, which is more direct and rude, but causes redundancy in the code. In the publishing and subscription mode, it is handled by the dispatch center uniformly, and subscribers and publishers do not interfere with each other, eliminating the dependence between publishers and subscribers. This allows for both decoupling and more fine-grained control. For example, if a publisher publishes a lot of messages, but does not want all subscribers to receive them, it can do some processing in the dispatch center, such as permission control. You can also do some throttling.

Observer mode is not publish subscribe mode

In JavaScript Design Patterns and Development Practices, the key to identifying patterns is intent, not structure. If patterns are distinguished by structure, publish-subscribe has one more middleware subscriber than observer, so publish-subscribe is different from observer. If the intent to distinguish patterns, they are all achieved a one-to-many dependency between objects, when an object’s state is changed, all depends on the object will be notified, and automatically updates, so they are the same pattern, publish-subscribe pattern is on the basis of the observer pattern optimization.