Stop confusing observer mode with publish subscribe mode!

Posted by oscar2 on Fri, 11 Feb 2022 15:51:21 +0100

Observer mode

There are usually two models in the observer model, one observer and one observed. Literally, when the observed person has some behavior or change, it will notify the observer, and the observer will deal with it according to this behavior or change.

Let's take a simple chestnut 🌰:

Now there is a landlord (observer) whose house is particularly popular, so there are a group of tenants (observers) who want to rent a house. The landlord will release some rental information. The tenants need to know in time to see the house.

class Landlord { // Landlord (observed)
    constructor() {
        this.observerList = [] // Observer list (tenants)
    }
    addObserver(observer) { // Add an observer (tenant)
        this.observerList.push(observer);
    }
    notify(data) {
        this.observerList.forEach(observer => observer.update(data))
    }
}


let person_id = 1
class Person { // Tenants who want to rent (observers)
    constructor() {
        this.id = person_id++
    }
    update(data) {
        console.log("tenant" + this.id + `-Received ${data.name},Come and see the house immediately!`)
    }
}

let landlord = new Landlord() // landlord or landlady

let person1 = new Person() // Tenant 1
let person2 = new Person() // Tenant 2
let person3 = new Person() // Tenant 3

// Tenants subscribe to landlord news
landlord.addObserver(person1)
landlord.addObserver(person2)
landlord.addObserver(person3)

// Landlord release information
landlord.notify({
    name: 'There are vacant houses in luxury houses in the city center',
    price: 10000
})

/* Print */
// The tenant 1- receives that there is a vacant house in the downtown mansion, and immediately comes to see the house!
// The tenant 2- received that there is a vacant house in the downtown mansion, and immediately came to see the house!
// The tenant 3- receives that there is a vacant house in the downtown mansion, and immediately comes to see the house!

Publish subscriber mode

So what is the publish subscriber model? Let's take a simple chestnut 🌰:

The landlord's house is so popular that more and more people want to subscribe to the rental information to see the house. The landlord thinks it's too troublesome, so he finds an intermediary (dispatching center) to help him manage. The landlord only needs to publish information to the intermediary, and the tenants only need to subscribe to the information of the intermediary. The landlord and the tenant are decoupled, and the landlord is finally quiet~

class Landlord { // Landlord (publisher)
    constructor(agency) {
        this.agency = agency
    }
    publish(type, price) {
        this.agency.publish(type, price) // Publish information to intermediaries
    }
}


let person_id = 1
class Person { // Tenants (subscribers) who want to rent a house
    constructor(agency) {
        this.id = person_id++
        this.agency = agency
    }
    subscribe(type){
        this.agency.subscribe(type, this);
    }
    update(type, price) {
        console.log(`tenant ${this.id} - Received ${type}Rental information, I think every month ${price}Very cheap!`)
    }
}


class Agency { // Intermediary (dispatching center)
    constructor() {
        this.dispatcher = {}
    }

    subscribe(type, subscriber) { // subscribe
        if (!this.dispatcher[type]) {
            this.dispatcher[type] = []
        }
        this.dispatcher[type].push(subscriber)
    }

    publish(type, price) { // release
        let subscribers = this.dispatcher[type]
        if (!subscribers || !subscribers.length) return
        subscribers.forEach(subscriber => {
            subscriber.update(type, price)
        });
    }
}

let agency = new Agency()  // agency

let person1 = new Person(agency) // Tenant 1
let person2 = new Person(agency) // Tenant 2
let person3 = new Person(agency) // Tenant 3

// Tenant subscription information
person1.subscribe('luxury house')
person2.subscribe('luxury house')
person3.subscribe('luxury house')
person3.subscribe('villa')

let landlord = new Landlord(agency) // landlord or landlady

// Landlord release information
landlord.publish('luxury house', 10000);
landlord.publish('villa', 20000);

/* Print */
// Tenant 1 - received the rental information of luxury house and thought 10000 per month was very cheap!
// Tenant 2 - received the rental information of luxury house and felt that 10000 per month was very cheap!
// Tenant 3 - received the rental information of luxury house and felt that 10000 per month was very cheap!
// Tenant 3 - received the rental information of the villa and thought 20000 per month was very cheap!

The same module has high cohesion or only applies to the same module; When the object and the execution of the first mock exam are not in the same module or component, the subscription publishing mode is suitable, which can be well decoupled and will not damage the encapsulation.

ending

I'm Zhou Xiaoyang, a front-end Mengxin. I wrote this article to record the problems encountered in my daily work and the contents of my study, so as to improve myself. If you think this article is useful to you, please praise and encourage me~

Topics: Javascript Front-end