乐趣区

关于javascript:别再把观察者模式和发布订阅模式搞混了

观察者模式

观察者模式中通常有两个模型,一个观察者和一个被观察者。从字面意思上了解,即被观察者产生某些行为或者变动时,会告诉观察者,观察者依据此行为或者变动做出解决。

咱们举个简略的栗子🌰:

当初有一个房东(被观察者),他的房子特地热门,所以有一群想租房子的租客(观察者),房东会公布一些租房信息,租客们须要及时的晓得,好来看房。

class Landlord {// 房东(被观察者)
    constructor() {this.observerList = [] // 观察者列表(租客们)
    }
    addObserver(observer) {// 增加一个观察者(租客)
        this.observerList.push(observer);
    }
    notify(data) {this.observerList.forEach(observer => observer.update(data))
    }
}


let person_id = 1
class Person {// 想要租房的租客(观察者)
    constructor() {this.id = person_id++}
    update(data) {console.log("租客" + this.id + `- 接管到 ${data.name},立即前来看房!`)
    }
}

let landlord = new Landlord() // 房东

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

// 租客们订阅房东音讯
landlord.addObserver(person1)
landlord.addObserver(person2)
landlord.addObserver(person3)

// 房东公布信息
landlord.notify({
    name: '市中心豪宅有空房',
    price: 10000
})

/* 打印 */
// 租客 1 - 接管到市中心豪宅有空房,立即前来看房!// 租客 2 - 接管到市中心豪宅有空房,立即前来看房!// 租客 3 - 接管到市中心豪宅有空房,立即前来看房!

公布订阅者模式

那什么是公布订阅者模式呢?再来举一个简略的栗子🌰:

房东的房子太热门了,想要订阅租房信息来看房的人越来越多,房东嫌太麻烦,于是找了中介 (调度核心) 来帮他治理,房东只须要对中介公布音讯,租客们也只须要订阅中介的音讯,房东与租客解耦,房东终于清静了~

class Landlord {// 房东(发布者)
    constructor(agency) {this.agency = agency}
    publish(type, price) {this.agency.publish(type, price) // 对中介公布信息
    }
}


let person_id = 1
class Person {// 想要租房的租客(订阅者)
    constructor(agency) {
        this.id = person_id++
        this.agency = agency
    }
    subscribe(type){this.agency.subscribe(type, this);
    }
    update(type, price) {console.log(` 租客 ${this.id} - 接管到 ${type}的租房信息,感觉每月 ${price}很便宜!`)
    }
}


class Agency {// 中介机构(调度核心)
    constructor() {this.dispatcher = {}
    }

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

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

let agency = new Agency()  // 中介机构

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

// 租客订阅信息
person1.subscribe('豪宅')
person2.subscribe('豪宅')
person3.subscribe('豪宅')
person3.subscribe('别墅')

let landlord = new Landlord(agency) // 房东

// 房东公布信息
landlord.publish('豪宅', 10000);
landlord.publish('别墅', 20000);

/* 打印 */
// 租客 1 - 接管到豪宅的租房信息,感觉每月 10000 很便宜!// 租客 2 - 接管到豪宅的租房信息,感觉每月 10000 很便宜!// 租客 3 - 接管到豪宅的租房信息,感觉每月 10000 很便宜!// 租客 3 - 接管到别墅的租房信息,感觉每月 20000 很便宜!

观察者模式,具备高内聚的特点,仅实用同模块或者同一组件内应用;当须要监听的对象和执行动作不在同一模块或者组件,用订阅公布模式是适宜的,能做到很好的解耦,不会毁坏封装。

结尾

我是周小羊,一个前端萌新,写文章是为了记录本人日常工作遇到的问题和学习的内容,晋升本人,如果您感觉本文对你有用的话,麻烦点个赞激励一下哟~

退出移动版