观察者模式(Observer)和发布-订阅者模式(Publish/Subscribe)区别
观察者模式:定义一对多的关系,让多个观察对象同时监听某一个主题对象,主题对象状态发生变化就通知所有观察者对象。所以它是由两类对像组成:Subject主题+Observer观察者。主题发布事件,观察者通过订阅事件观察主题。
Observer模式提供给关联对象一种同步通信的手段,使得主题和观察者之间保持同步通信。
function observar(oldVal,newVal){
console.log(`name属性值从${oldVal}改变为${newVal}`);
}
class TargetObj{
constructor(age,name){
this.name = name;
this.age = age;
}
set name(val){
observar(name,val);
name = val;
}
}
let targetObj = new TargetObj(22,'miya');
targetObj.name = 'Lily';
console.log(targetObj)
//name属性值从改变为miya
//name属性值从miya改变为Lily
阮一峰大神在介绍Reflect时候,使用Proxy写了一个观察者模式的代码:
//观察者队列
const queuedObservers = new Set();
const observe = fn => queuedObservers.add(fn);
function print(){
console.log(`${person.name},${person.age}`);
}
//将观察者放入队列中
observe(print);
const person = new Proxy({name:'张三',age:22},{
set(target,key,value,receiver){
const result = Reflect.set(target,key,value,receiver);
queuedObservers.forEach(observer => observer());
return result;
}
})
person.name = '李四';
//李四,22
上面代码可以看出,观察者模式是:Observer在Subject主题对象特定活动状态改变时候获取通知。主题Subject需要一个数组类型来存储所有的订阅者。Subject和Observer之间存在依赖关系,存在耦合。
JavaScript中的事件监听机制可以理解为观察者模式,通过onclick事件绑定,然后事件主动触发。
发布—订阅模式:完全解耦,发布者和订阅者彼此不知道对方的存在,二者共享一个自定义事件的名称。它的优点非常明显,一为时间上的解耦,二为对象之间的解耦。
观察者模式中,目标对象也就是Subject管理观察者,发布-订阅模式中多了一个中间层通道。
//发布-订阅
var Event = (function(){
var clientList = {},
listen,
trigger,
remove;
listen = function(key,fn){
if(!clientList[key]){
clientList[key] = [];
}
clientList[key].push(fn);
}
trigger = function(){
var key = Array.prototype.shift.call(arguments),
fns = clientList[key];
if(!fns || fns.length === 0){
return false;
}
for(var i = 0,fn;fn = fns[i++];){
fn.apply(this,arguments);
}
}
remove = function(key,fn){
var fns = clientList[key];
if(!fns) return false;
if(!fn){
fns && (fns.length = 0);
}else{
for(var i = 0,_fn;_fn = fns[i++];){
if(fn === _fn){
fns.splice(i,1);
}
}
}
}
return {
listen:listen,
trigger:trigger,
remove:remove
}
})()
Event.listen('LondonAirPlay',function(price){
console.log(`the price is ${price}`)
})
Event.trigger('LondonAirPlay',3000)
//the price is 3000
订阅者想要订阅伦敦的机票,通过Event对象来实现了,Event对象具有listen订阅,trigger发布,remove取消等功能,订阅者和发布者之间完全是不认识的,Event类似于一个“中介者”,将订阅者和发布者联系起来。

总结:
1,Observer模式,观察者是知道Subject主题的,目标主题一直保持对观察者的记录,而publish-subscribe模式中,订阅者和发布者互相不知道对方,通过消息代理进行通信。
2,Observer模式中,观察者和主题之间存在依赖耦合关系,而发布订阅者模式则完全松耦合的。
3,多数情况下,Observer模式是同步,例如事件触发,而发布-订阅者使用的消息队列模式,大多数处理异步事件。
【完】
观察者模式(Observer)和发布-订阅者模式(Publish/Subscribe)区别的更多相关文章
- [JS设计模式]:观察者模式(即发布-订阅者模式)(4)
简介 观察者模式又叫发布---订阅模式,它定义了对象间的一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知. 举一个现实生活中的例子,例如小 ...
- “一切都是消息”--MSF(消息服务框架)之【发布-订阅】模式
在上一篇,“一切都是消息”--MSF(消息服务框架)之[请求-响应]模式 ,我们演示了MSF实现简单的请求-响应模式的示例,今天来看看如何实现[发布-订阅]模式.简单来说,该模式的工作过程是: 客户端 ...
- “一切都是消息”--iMSF(即时消息服务框架)之【发布-订阅】模式
MSF的名字是 Message Service Framework 的简称,由于目前框架主要功能在于处理即时(immediately)消息,所以iMSF就是 immediately Message S ...
- ActiveMQ发布-订阅消息模式
一.订阅杂志我们很多人都订过杂志,其过程很简单.只要告诉邮局我们所要订的杂志名.投递的地址,付了钱就OK.出版社定期会将出版的杂志交给邮局,邮局会根据订阅的列表,将杂志送达消费者手中.这样我们就可以看 ...
- (三)ActiveMQ之发布- 订阅消息模式实现
一.概念 发布者/订阅者模型支持向一个特定的消息主题发布消息.0或多个订阅者可能对接收来自特定消息主题的消息感兴趣.在这种模型下,发布者和订阅者彼此不知道对方.这种模式好比是匿名公告板.这种模式被概括 ...
- JS 设计模式八 -- 发布订阅者模式
概念 发布---订阅模式又叫观察者模式,它定义了对象间的一种一对多(一个发布,多个观察)的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知. 优点 1 ...
- 学习javascript设计模式之发布-订阅(观察者)模式
1.发布-订阅模式又叫观察者模式,它定义对象之间一种一对多的依赖关系. 2.如何实现发布-订阅模式 2-1.首先指定好发布者 2-2.给发布者添加一个缓冲列表,用户存放回调函数以便通知订阅者 2-3. ...
- ionic3 发布订阅者模式实现
在ionic3 中实现订阅发布模式,需要用到Events. Events下面有三个方法 events.subscribe() 订阅 events.publish() 发布 events.unsub ...
- 把酒言欢话聊天,基于Vue3.0+Tornado6.1+Redis发布订阅(pubsub)模式打造异步非阻塞(aioredis)实时(websocket)通信聊天系统
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_202 "表达欲"是人类成长史上的强大"源动力",恩格斯早就直截了当地指出,处在蒙昧时代即低 ...
随机推荐
- HttpClient简介与案例分析
HttpClient简介 HTTP 协议可能是现在 Internet 上使用得最多.最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源.虽然在 JDK 的 jav ...
- python易错知识集合
本篇用于记录在写leetcode时遇到的python易错知识. 2019.8.29 1.Python range() 函数用法: range(start, stop[, step]) start: 计 ...
- 在virtualenv中安装NumPy、 SciPy、 scikit-learn、 matplotlib
首先要进入对应的虚拟环境 然后安装包 这里把安装源改成使用豆瓣的源进行下载 这样的话 下载速度会快很多 安装numpy包 pip install numpy -i https://pypi ...
- SHELL用法五(Case语句)
1.SHELL编程Case语句案例实战 1)Case选择条件语句的格式: case $INPUT in Pattern1) 语句1 ;; Pattern2) 语句2 ;; esac 2)Case语句企 ...
- linux上python3的安装
我这里使用的时centos7-mini,centos系统本身默认安装有python2.x,版本x根据不同版本系统有所不同,可通过 python --V 或 python --version 查看系统自 ...
- idea 使用sonarlint报错解决方案
在idea使用sonarlint可能出现以下报错: Plugin 'org.sonarlint.idea' failed to initialize and will be disabled. Ple ...
- 华为云linux服务器部署TensorFlow-gpu全攻略
最近在玩谷歌新开源的自然语言模型bert,最开始是在google的免费GPU上面来弄的(这个部分其实也是可以写一个教程的,中间坑也挺多).但谷歌比较坑人,小数据集还行,大点的数据集训练耗费时间长,再加 ...
- Microsoft Hyperlapse——让第一人称视频更快更流畅
Hyperlapse--让第一人称视频更快更流畅" title="Microsoft Hyperlapse--让第一人称视频更快更流畅"> 职业摄影师Nick Di ...
- Python 字符编码判断
题记 在获取中文字符的时候,如果出现乱码的情况,我们需要了解当前的字符串的编码形式.使用下面两种方法可以判断字符串的编码形式. 法一: isinstance(s, str) 用来判断是否为一般字符串 ...
- ubuntu16.04安装mysql5.6
apt-get install software-properties-commonsudo add-apt-repository 'deb http://archive.ubuntu.com/ubu ...