3

观察者模式

观察者模式中通常有两个模型,一个观察者和一个被观察者。从字面意思上理解,即被观察者发生某些行为或者变化时,会通知观察者,观察者根据此行为或者变化做出处理。

我们举个简单的栗子🌰:

现在有一个房东(被观察者),他的房子特别抢手,所以有一群想租房子的租客(观察者),房东会发布一些租房信息,租客们需要及时的知道,好来看房。

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很便宜!

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

结尾

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

小绵羊
70 声望517 粉丝