这里了解一下JavaScript中的发布订阅模式和观察者模式,观察者模式是24种基础设计模式之一。

设计模式的背景

设计模式并非是软件开发的专业术语,实际上设计模式最早诞生于建筑学。

设计模式的定义是,在面向对象软件设计过程中,针对特定问题的简洁而优雅的解决方案。通俗一点说,设计模式是在某种场合下对某个问题的一种解决方案。再通俗一点说,设计模式就是给面向对象软件开发中的一些好的设计取名字。

这些好的设计模式并不是谁发明的,而是早已存在于软件开发中。一个稍有经验的程序员也许在不知不觉中数次使用过这些设计模式。GoF(Gang of Four,四人组)最大的功绩是把这些好的设计从浩瀚的面向对象世界中挑选出来,并且给予它们一个好听又好记的名字。

设计模式并不直接用来完成代码的编写,而是描述在各种不同的情况下,要怎么解决问题的一种方案。设计模式不是一个约束的机制,而是一种指导思想,一种写代码的形式。每种语言对于各种设计模式都有自己的实现方式,对于某些设计模式来说,可能在某些语言下并不适用,比如工厂方法模式对于JavaScript,因此设计模式应该被用在正确的地方。而哪些才算是正确的地方,只有在深刻地理解了设计模式的意图之后,再结合项目的实际场景才会知道。

设计模式的社区一直在发展。GoF在1995年提出了23种设计模式,但实际上设计模式并不仅仅局限于这23中,后面增加到了24种。在这20多年的时间里,也许有更多的设计模式已经被人发现并总结出来,比如一些JavaScript的书籍中会提到模块化模式、沙箱模式等。只是这些设计模式能否被世人公认并流传下来还有待时间验证。

观察者模式(Observer Pattern)

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

观察者模式有一个别名叫做发布-订阅模式,或者说叫订阅-发布模式,订阅者和订阅目标是联系在一起的,当订阅目标发生改变的时候,逐个通知订阅者。这里可以用报纸期刊的订阅来形象地说明,当你订阅了一份报纸,那么每天都会有一份最新的报纸送到你的手上。有多少人订阅报纸,报社就会发多少份报纸,报纸和订报纸的客户就是一对多的依赖关系。

发布订阅模式(Pub-Sub Pattern)

其实24种基本设计模式种并没有发布订阅模式,它只是观察者模式的一个别称。但是经过时间的沉淀,它似乎已经变得强大起来,已经独立于观察者模式,成为另外一种不同的设计模式。

在现在的发布订阅模式中,成为发布者的消息发送者不会将消息直接发送给订阅者,这就意味着发布者和订阅者不知道彼此的存在。在发布者和订阅者之间存在第三个组件,成为消息代理或调度中心或中间件,它维持着发布者和订阅者之间的联系,过滤所有发布者传入的消息并相应地分发它们给订阅者。

举一个例子,你在微博上关注了A,同时其他很多人也关注了A,那么当A发布动态的时候,微博就会为你们推送这条动态。在这里,A就是发布者,你则是订阅者,微博就是调度中心,你和A之间是没有直接的消息往来的,消息的推送全是通过微博来协调的。

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

上面说到了发布订阅模式原来是观察者模式的一个别称,但是现在发布订阅模式渐渐地变成了独立于观察者模式的存在,也就是说两者之间存在了区别。

观察者模式是观察者(Observer)直接订阅(Subscribe)主题(Subject),当主题被激活的时候,会触发(Fire Event)观察者里的事件。

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

从这里可以看出,观察者模式模式和发布订阅模式最大的区别就是发布订阅模式有一个事件调度中心。观察者模式是由具体的目标调度,每个被订阅的目标里面都需要有对观察者的处理,这种处理方式比较直接粗暴,但是会造成代码的冗余。而发布订阅模式统一由调度中心进行处理,订阅者和发布者互补干扰,消除了发布者和订阅者之间的依赖。这样不仅实现了解耦,还有就是可以实现更细粒度的一些控制。比如发布者发布了很多消息,但是不想所有的订阅者都接收到,就可以在调度中心做一些处理,类似于权限控制制类的,还可以做一些节流的操作。

发布订阅模式是不是观察者模式的争论

关于这个问题的回答出现了两级分化的情况。有的人认为发布订阅者模式就是观察者模式,也有的人认为观察者模式与发布订阅模式很不一样。

如果以结构来分辨设计模式的话,发布订阅模式比观察者模式多了一个中间件订阅器,所以发布订阅模式是不同于观察者模式的;如果以意图来分辨模式,它们都是实现了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知,并自动更新,这时候就可以将它们看作是同一种模式,发布订阅模式只是在观察者模式的基础上做了升级优化。

实际上,不管它们是不是同一种设计模式,它们的实现方式的确存在差别,在使用的时候应该要根据实际的场景去判断、选择使用观察者模式还是发布订阅模式。

"有些人注定是等待别人的,有些人注定是被别人等的。"

javascript中的发布订阅模式与观察者模式的更多相关文章

  1. Javascript中理解发布--订阅模式

    Javascript中理解发布--订阅模式 阅读目录 发布订阅模式介绍 如何实现发布--订阅模式? 发布---订阅模式的代码封装 如何取消订阅事件? 全局--发布订阅对象代码封装 理解模块间通信 回到 ...

  2. 【转】Javascript中理解发布--订阅模式

    Javascript中理解发布--订阅模式 阅读目录 发布订阅模式介绍 发布---订阅模式又叫观察者模式,它定义了对象间的一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时 ...

  3. [转] Javascript中理解发布--订阅模式

    发布订阅模式介绍 发布---订阅模式又叫观察者模式,它定义了对象间的一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知. 现实生活中的发布- ...

  4. [转] JavaScript设计模式之发布-订阅模式(观察者模式)-Part1

    <JavaScript设计模式与开发实践>读书笔记. 发布-订阅模式又叫观察者模式,它定义了对象之间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖它的对象都将得到通知. 例如 ...

  5. 浅谈vue响应式原理及发布订阅模式和观察者模式

    一.Vue响应式原理 首先要了解几个概念: 数据响应式:数据模型仅仅是普通的Javascript对象,而我们修改数据时,视图会进行更新,避免了繁琐的DOM操作,提高开发效率. 双向绑定:数据改变,视图 ...

  6. JavaScript设计模式(发布订阅模式)

    发布—订阅模式又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知.在JavaScript开发中,我们一般用事件模型来替代传统的发布—订阅模式 ...

  7. Javascript设计模式之发布-订阅模式

    简介 发布-订阅模式又叫做观察者模式,他定义了一种一对多的依赖关系,即当一个对象的状态发生改变的时候,所有依赖他的对象都会得到通知. 回忆曾经 作为一名前端开发人员,给DOM节点绑定事件可是再频繁不过 ...

  8. javaScript设计模式:发布订阅模式

    发布订阅模式的思想是在观察者模式的基础上演变而来,在观察者模式中客户端监听到对象某个行为就触发对应任务程序.而在发布订阅模式中依然基于这个核心思想,所以有时候也会将两者认为是同一种设计模式.它们的不同 ...

  9. JavaScript设计模式_05_发布订阅模式

    发布-订阅模式,定义了对象间的一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖它的对象都将得到通知.发布-订阅模式是使用比较广泛的一种模式,尤其是在异步编程中. /* * pre:发布-订阅 ...

随机推荐

  1. Java Serializable:明明就一个空的接口嘛

    对于 Java 的序列化,我一直停留在最浅显的认知上——把那个要序列化的类实现 Serializbale 接口就可以了.我不愿意做更深入的研究,因为会用就行了嘛. 但随着时间的推移,见到 Serial ...

  2. Kafka生产消费API JAVA实现

    Maven依赖: <dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka- ...

  3. 好久没玩laravel了,今天玩下Laravel项目迁移步骤

    .在新的目录中克隆git远程版本库 .执行composer install安装依赖 .执行php artisan key:generate生成key 好久没玩laravel了,今天玩下Laravel项 ...

  4. Gallery -- 横向不断滚动 demo

    <%@ Page Language="C#" AutoEventWireup="true" %> <!DOCTYPE html> < ...

  5. 17个常见的Python运行时错误

    对于刚入门的Pythoner在学习过程中运行代码是或多或少会遇到一些错误,刚开始可能看起来比较费劲.随着代码量的积累,熟能生巧当遇到一些运行时错误时能够很快的定位问题原题.下面整理了常见的17个错误, ...

  6. Java 构造结构私有化

    Java 构造结构私有化 单例设计模式:(Singleton) 在一般情况下,一个类只有通过产生对象之后才可以操作这个类. class Singleton { public void print() ...

  7. CocoPods原理

    CocoaPods 的原理是将所有的依赖库都放到另一个名为Pods的项目中, 然而让住项目依赖Pods项目, 这样,源码管理工作任务从主项目移到了Pods项目中. 1.Pods项目最终会编译成一个名为 ...

  8. Android JS打开原生应用

    设置App通过网页JS,唤醒打开本地应用. 在AndroidManifest 中,在应用启动页配置下,添加android:exported="true",设置category 添加 ...

  9. PHP将字符串转数组

    explode(',',$arr_string) //将字符串转数组 $arr_string = '1,2,3'; $arr = explode(',',$arr_string); dump($arr ...

  10. Linux根目录下各目录含义

    /boot:系统启动的相关文件,比如内核,grub /etc:配置文件 /dev:设备文件 /root:root用户的家目录 /home:用户家目录 /lib:库文件 /bin:用户的命令文件 /sb ...