前端-观察者模式和发布订阅模式

目录

观察者模式介绍:

意图:

主要解决:

何时使用:

如何解决:

关键代码:

优点:

TS代码实现

发布订阅模式介绍

JS代码实现

观察者模式 和 发布订阅模式的区别

前端发布订阅模式使用场景


观察者模式介绍:

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。

观察者模式定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知,并自动更新。观察者模式属于行为型模式,行为型模式关注的是对象之间的通讯,观察者模式就是观察者和被观察者之间的通讯。

意图:

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

主要解决:

一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。

何时使用:

一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。

如何解决:

使用面向对象技术,可以将这种依赖关系弱化。

关键代码:

在抽象类里有一个 ArrayList(数组变量) 存放观察者们。

优点:

1、观察者和被观察者是抽象耦合的。 2、建立一套触发机制。

TS代码实现

// 观察者模式 

// 咖啡厅的吧台---被观察者
class Subject {
    private state: number = 0
    // 存放观察者(顾客)的数组
    private observers: Observer[] = []

    getState() {
        return this.state
    }
    // 更新咖啡制作的状态,完没完成
    setState(newState: number) {
        // 更新状态
        this.state = newState
        // 把更新的状态广播给所有顾客
        this.notify()
    }
    // 添加新的顾客
    attach(observer: Observer) {
        this.observers.push(observer)
    }
    // 通知所有顾客
    notify() {
        this.observers.forEach(observer=>{
            // 调用 Observer 类中的方法
            observer.update(this.state)
        })
    }
}
// 每个顾客---观察者
class Observer { 
    name:string
    constructor(name:string) {
        this.name = name
    }
    // 顾客接收到的通知
    update(state:number){
        console.log(`${this.name} updated , state is ${state}`)
    }
}

// 建立咖啡厅
const sub = new Subject()
// 顾客进店
const observer1 = new Observer('A')
const observer2 = new Observer('B')
// 添加顾客
sub.attach(observer1)
sub.attach(observer2)

// 咖啡做完了 广播给在咖啡店的所有员工
sub.setState(1)

前端观察者模式的使用场景

- DOM 事件

- 组件生命周期

- Vue watch监听

- Vue 组件更新过程

- 异步回调 (带有回调函数的,如 Promise 的 then 定时器回调)

发布订阅模式介绍

订阅者(Subscriber)把自己想订阅的事件注册(Subscribe)到调度中心(Topic),当发布者(Publisher)发布该事件(Publish topic)到调度中心,也就是该事件触发时,由调度中心统一调度(Fire Event)订阅者注册到调度中心的处理代码。

发布订阅模式中统一由调度中心进行处理,订阅者和发布者互不干扰,消除了发布者和订阅者之间的依赖。这样一方面实现了解耦,还有就是可以实现更细粒度的一些控制。比如发布者发布了很多消息,但是不想所有的订阅者都接收到,就可以在调度中心做一些处理,类似于权限控制之类的。还可以做一些节流操作。

JS代码实现

//定义一家猎人工会
//主要功能包括任务发布大厅(topics),以及订阅任务(subscribe),发布任务(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)
        }
    }
}

//定义一个猎人类
//包括姓名,级别
function Hunter(name, level) {
    this.name = name
    this.level = level
}
//猎人可在猎人工会发布订阅任务
Hunter.prototype.subscribe = function (topic, fn) {
    console.log(this.level + '猎人' + this.name + '订阅了狩猎' + topic + '的任务')
    HunterUnion.subscribe(topic, fn)
}
Hunter.prototype.publish = function (topic, money) {
    console.log(this.level + '猎人' + this.name + '发布了狩猎' + topic + '的任务')
    HunterUnion.publish(topic, money)
}

//猎人工会走来了几个猎人
let hunterMing1 = new Hunter('小明', '黄金')
let hunterJin1 = new Hunter('小金', '白银')
let hunterZhang1 = new Hunter('小张', '黄金')
let hunterPeter1 = new Hunter('Peter', '青铜')

//小明,小金,小张分别订阅了狩猎tiger的任务
hunterMing.subscribe('tiger', function (money) {
    console.log('小明表示:' + (money > 200 ? '' : '不') + '接取任务')
})
hunterJin.subscribe('tiger', function (money) {
    console.log('小金表示:接取任务')
})
hunterZhang.subscribe('tiger', function (money) {
    console.log('小张表示:接取任务')
})
//Peter订阅了狩猎sheep的任务
hunterPeter.subscribe('sheep', function (money) {
    console.log('Peter表示:接取任务')
})

//Peter发布了狩猎tiger的任务
hunterPeter.publish('tiger', 198)

//猎人们发布(发布者)或订阅(观察者/订阅者)任务都是通过猎人工会(调度中心)关联起来的,他们没有直接的交流。

观察者模式 和 发布订阅模式的区别

观察者模式和发布订阅模式最大的区别就是发布订阅模式有个事件调度中心。

前端发布订阅模式使用场景

Vue2中自带的 自定义事件,on注册,emit 触发;注意使用完成后及时 off 注销掉自定义事件;

Vue3中推荐使用的 mitt ,on注册,emit 触发;注意使用完成后及时 off 注销掉自定义事件;

借鉴:(63条消息) 发布订阅模式与观察者模式_hfhan_872914334的博客-CSDN博客_订阅者模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值