它们不一样!透析【观察者模式】和【发布订阅模式】

简介: 观察者模式常常会和发布订阅模式一起哪来比较,它们二者同样重要。

观察者模式常常会和发布订阅模式一起哪来比较,它们二者同样重要。


直观的例子:

Vue 的双向绑定原理用到了发布订阅模式的思想;

在函数式编程中,广泛应用观察者设计模式思想。

但是,可能在平常,写业务代码,真实用到这两样设计思想的并不多,只好在做技术总结的时候复盘一下,温故再温故啦。(也有一种可能是:或许是运用还不是很熟,在有些场景,可以用到,但会忽视掉)


闲话少说,奥利给,冲它!!


简介



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

后者比前者多了一个中间商


观察者模式:

  1. 观察者 Observer
  2. 被观察者 Subject


发布订阅模式:

  1. 订阅者 subscriber (类似于观察者)
  2. 发布者 publisher (类似于被观察者)
  3. 调度中心(中间商)

一图胜千言:

image.png


有了以上的基本认识,咱们再展开说说~~


观察者模式



观察者模式之前写过 juejin.cn/post/707289…,这里再优化下注解,并再封装一个 Observer 类,由此创建多个 Observer 实例:


class Subject{// 被观察者
    constructor(){
        this.observers=[]
    }
    add(observer){
        this.observers.push(observer)
    }
    notify(newMsg){
        this.observers.forEach(i=>i.consoleFn(newMsg))
    }
}
class Observer{// 观察者
    constructor(name){
        this.name=name
    }
    consoleFn(newMsg){
        console.log(newMsg + '======》》》'+ this.name +'收到了')
    }
}
let sub = new Subject()
let observer1 = new Observer("观察者1")
let observer2 = new Observer("观察者2")
sub.add(observer1) // Observer1 观察 sub
sub.add(observer2) // Observer2 观察 sub
sub.notify("我是被观察者,我发布了一个信息!") // sub 发布消息
// 我是被观察者,我发布了一个信息!======》》》观察者1收到了
// 我是被观察者,我发布了一个信息!======》》》观察者2收到了


要点小结:

  1. 写一个 Subject 类,有:添加观察者 add、通知观察者 notify 方法(也可补充写删除观察者 del 方法);
  2. 写一个 Observer 类,打印出所接收到的信息;
  3. 实例化一个被观察者;
  4. 实例化一个或多个观察者;
  5. 用 add 方法进行绑定;
  6. 用 notify 方法进行通知;


发布订阅模式



发布订阅模式,就是比观察者模式多了一个“中间商”,也叫调度中心;

发布者 publisher == 被观察者 Subject

订阅者 subscriber == 观察者 Observer


调度中心 Event Channel,或者说是大家熟悉的 Vue 双向绑定中的 Dep,依赖管理中心、订阅中心


// 发布者 Publisher
class Pub {
    constructor() {
        this.deps = [];
    }
    addDep(dep) {
        this.deps.push(dep);
    }
    publish(dep) {
        this.deps.forEach(item => item === dep && item.notify());
    }
}
// 订阅者 Subscriber
class Sub {
    constructor(val) {
        this.val = val;
    }
    update(callback) {
        callback(this.val)
    }
}
// 调度中心
class Dep {
    constructor(callback) { // 核心是这个 callback 函数;
        this.subs = [];
        this.callback = callback;
    }
    addSub(sub) {
        this.subs.push(sub);
    }
    notify() {
        this.subs.forEach(item => item.update(this.callback));
    }
}
let pub = new Pub() // 实例化一个发布者
// 实例化一个调度中心,传入一个用于处理数据的函数;
const dep1 = new Dep((data) =>
              console.log('我是调度中心,我先把消息处理一下,然后发给 ===》》》', data)) 
let sub1 = new Sub("订阅者1") // 实例化订阅者1
let sub2 = new Sub("订阅者2") // 实例化订阅者2
pub.addDep(dep) // 发布者绑定调度中心
dep.addSub(sub1) // 调度中心添加订阅者1
dep.addSub(sub2) // 调度中心添加订阅者2
pub.publish(dep) // 发布者把消息推给调度者
// 我是调度中心,我先把消息处理下先 订阅者1
// 我是调度中心,我先把消息处理下先 订阅者2


要点小结:


  1. 写一个 Pub 发布者类,有添加调度中心 addDep,推送消息 publish 两个方法;
  2. 写一个 Sub 订阅者类,有获取信息 update 方法;
  3. 写一个 Dep 调度中心类,有添加订阅者 addSub,通知消息 notify 两个方法;
  4. 实例化发布者;
  5. 实例化 1 个或多个调度的对象;
  6. 实例化 1 个或多个订阅者对象;
  7. 发布者绑定调度中心;
  8. 调度中心绑定订阅者;
  9. 发布者发布消息;


由上面的例子可见,发布者不会把消息直接发给订阅者,而是会先发给调度中心,再由调度中心发给订阅者;


有小朋友就问了:不就比观察者模式多了个“中间商”,有这个必要吗??


答案是肯定的!当然有!!


观察者模式中,被观察者直接把消息发给观察者,这是强绑定的,作为观察者,只有我主动绑定了我要观察的对象,我才能知道它发的消息给我;

image.png


而在发布订阅模式中,发布者和订阅者是 完全解耦 的,作为发布者,我把消息发给调度中心之后,我就不用管了,我只负责发布消息,不管谁接收;同样,订阅者,只负责接收调度中心来的消息,不用管是哪个发布者发的;


image.png


高内聚、低耦合,是我们的最终追求!!


小结



观察者模式和发布订阅模式,想想还是挺有意思的;


为什么要这么演进,我尝试用一个实际生活场景解释 —— 领导的发言稿,要打印出来,供下面的同事学习;


做法1:没有任何设计思想时,每个人都去找领导要这个稿子的电子版,然后去打印;

做法2:用观察者模式设计思想,领导主动把这个电子稿以邮件形式群发给大家,让大家自行打印;如果稿件有内容变动的话,领导再主动推送给大家一份新的;


做法3:用发布订阅者模式设计思想,领导发给秘书,秘书再分发给大家;因为稿件可能存在部分敏感信息,需要经过处理,分发给不同的同事,比如某类员工只能看其中一部分内容;


相关文章
|
7月前
|
消息中间件 存储 Cloud Native
揭秘发布订阅模式:让消息传递更高效
揭秘发布订阅模式:让消息传递更高效
揭秘发布订阅模式:让消息传递更高效
|
7月前
|
设计模式 前端开发 JavaScript
观察者模式 vs 发布-订阅模式:两种设计模式的对决!
欢迎来到前端入门之旅!这个专栏是为那些对Web开发感兴趣、刚刚开始学习前端的读者们打造的。无论你是初学者还是有一些基础的开发者,我们都会在这里为你提供一个系统而又亲切的学习平台。我们以问答形式更新,为大家呈现精选的前端知识点和最佳实践。通过深入浅出的解释概念,并提供实际案例和练习,让你逐步建立起一个扎实的基础。无论是HTML、CSS、JavaScript还是最新的前端框架和工具,我们都将为你提供丰富的内容和实用技巧,帮助你更好地理解并运用前端开发中的各种技术。
|
2月前
|
设计模式 消息中间件 安全
C# 一分钟浅谈:观察者模式与订阅发布模式
【10月更文挑战第11天】本文介绍了观察者模式和订阅发布模式,这两种设计模式主要用于实现对象间的解耦。观察者模式通过事件和委托实现一个对象状态改变时通知多个依赖对象;订阅发布模式则通过事件聚合器实现发布者与订阅者之间的解耦。文章详细探讨了这两种模式的实现方式、常见问题及避免方法,帮助开发者在实际项目中更好地应用这些模式,提升代码的可维护性和扩展性。
80 1
|
1天前
|
设计模式 消息中间件 供应链
前端必须掌握的设计模式——发布订阅模式
发布订阅模式(Publish-Subscribe Pattern)是一种设计模式,类似于观察者模式,但通过引入第三方中介实现发布者和订阅者的解耦。发布者不再直接通知订阅者,而是将消息发送给中介,由中介负责分发给订阅者。这种方式提高了异步支持和安全性,适合复杂、高并发场景,如消息队列和流处理系统。代码实现中,通过定义发布者、订阅者和中介接口,确保消息的正确传递。此模式在前端开发中广泛应用,例如Vue的数据双向绑定。
|
6月前
|
设计模式
观察者模式-大话设计模式
观察者模式-大话设计模式
|
7月前
|
消息中间件 缓存 监控
【C++ 观察者模式的应用】跨进程观察者模式实战:结合ZeroMQ和传统方法
【C++ 观察者模式的应用】跨进程观察者模式实战:结合ZeroMQ和传统方法
268 1
|
7月前
|
设计模式
设计模式-观察者(发布订阅)模式
设计模式-观察者(发布订阅)模式
|
7月前
行为型 观察者模式(发布订阅)
行为型 观察者模式(发布订阅)
46 0
|
设计模式 开发者
设计模式之订阅发布模式
设计模式之订阅发布模式
247 0
|
设计模式
关于观察者模式/发布订阅模式我所知道的
关于观察者模式/发布订阅模式我所知道的
109 0