观察者模式:定义一对多的关系,让多个观察对象同时监听某一个主题对象,主题对象状态发生变化就通知所有观察者对象。所以它是由两类对像组成:Subject主题+Observer观察者。主题发布事件,观察者通过订阅事件观察主题。

Observer模式提供给关联对象一种同步通信的手段,使得主题和观察者之间保持同步通信

  1. function observar(oldVal,newVal){
  2. console.log(`name属性值从${oldVal}改变为${newVal}`);
  3. }
  4. class TargetObj{
  5. constructor(age,name){
  6. this.name = name;
  7. this.age = age;
  8. }
  9. set name(val){
  10. observar(name,val);
  11. name = val;
  12. }
  13. }
  14. let targetObj = new TargetObj(22,'miya');
  15. targetObj.name = 'Lily';
  16. console.log(targetObj)
  17. //name属性值从改变为miya
  18. //name属性值从miya改变为Lily 

阮一峰大神在介绍Reflect时候,使用Proxy写了一个观察者模式的代码:

  1. //观察者队列
  2. const queuedObservers = new Set();
  3. const observe = fn => queuedObservers.add(fn);
  4. function print(){
  5. console.log(`${person.name},${person.age}`);
  6. }
  7. //将观察者放入队列中
  8. observe(print);
  9. const person = new Proxy({name:'张三',age:22},{
  10. set(target,key,value,receiver){
  11. const result = Reflect.set(target,key,value,receiver);
  12. queuedObservers.forEach(observer => observer());
  13. return result;
  14. }
  15. })
  16. person.name = '李四';
  17. //李四,22

上面代码可以看出,观察者模式是:Observer在Subject主题对象特定活动状态改变时候获取通知。主题Subject需要一个数组类型来存储所有的订阅者。Subject和Observer之间存在依赖关系,存在耦合。

JavaScript中的事件监听机制可以理解为观察者模式,通过onclick事件绑定,然后事件主动触发。

发布—订阅模式:完全解耦,发布者和订阅者彼此不知道对方的存在,二者共享一个自定义事件的名称。它的优点非常明显,一为时间上的解耦,二为对象之间的解耦。

观察者模式中,目标对象也就是Subject管理观察者,发布-订阅模式中多了一个中间层通道。

  1. //发布-订阅
  2. var Event = (function(){
  3. var clientList = {},
  4. listen,
  5. trigger,
  6. remove;
  7. listen = function(key,fn){
  8. if(!clientList[key]){
  9. clientList[key] = [];
  10. }
  11. clientList[key].push(fn);
  12. }
  13. trigger = function(){
  14. var key = Array.prototype.shift.call(arguments),
  15. fns = clientList[key];
  16. if(!fns || fns.length === 0){
  17. return false;
  18. }
  19. for(var i = 0,fn;fn = fns[i++];){
  20. fn.apply(this,arguments);
  21. }
  22. }
  23. remove = function(key,fn){
  24. var fns = clientList[key];
  25. if(!fns) return false;
  26. if(!fn){
  27. fns && (fns.length = 0);
  28. }else{
  29. for(var i = 0,_fn;_fn = fns[i++];){
  30. if(fn === _fn){
  31. fns.splice(i,1);
  32. }
  33. }
  34. }
  35. }
  36. return {
  37. listen:listen,
  38. trigger:trigger,
  39. remove:remove
  40. }
  41. })()
  42. Event.listen('LondonAirPlay',function(price){
  43. console.log(`the price is ${price}`)
  44. })
  45. Event.trigger('LondonAirPlay',3000)
  46. //the price is 3000 

订阅者想要订阅伦敦的机票,通过Event对象来实现了,Event对象具有listen订阅,trigger发布,remove取消等功能,订阅者和发布者之间完全是不认识的,Event类似于一个“中介者”,将订阅者和发布者联系起来。

总结:

1,Observer模式,观察者是知道Subject主题的,目标主题一直保持对观察者的记录,而publish-subscribe模式中,订阅者和发布者互相不知道对方,通过消息代理进行通信。

2,Observer模式中,观察者和主题之间存在依赖耦合关系,而发布订阅者模式则完全松耦合的。

3,多数情况下,Observer模式是同步,例如事件触发,而发布-订阅者使用的消息队列模式,大多数处理异步事件。

【完】

如来者,无所从来,亦无所去,故名如来。
                                                                 ——鸠摩罗什 《金刚经》

观察者模式(Observer)和发布-订阅者模式(Publish/Subscribe)区别的更多相关文章

  1. [JS设计模式]:观察者模式(即发布-订阅者模式)(4)

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

  2. “一切都是消息”--MSF(消息服务框架)之【发布-订阅】模式

    在上一篇,“一切都是消息”--MSF(消息服务框架)之[请求-响应]模式 ,我们演示了MSF实现简单的请求-响应模式的示例,今天来看看如何实现[发布-订阅]模式.简单来说,该模式的工作过程是: 客户端 ...

  3. “一切都是消息”--iMSF(即时消息服务框架)之【发布-订阅】模式

    MSF的名字是 Message Service Framework 的简称,由于目前框架主要功能在于处理即时(immediately)消息,所以iMSF就是 immediately Message S ...

  4. ActiveMQ发布-订阅消息模式

    一.订阅杂志我们很多人都订过杂志,其过程很简单.只要告诉邮局我们所要订的杂志名.投递的地址,付了钱就OK.出版社定期会将出版的杂志交给邮局,邮局会根据订阅的列表,将杂志送达消费者手中.这样我们就可以看 ...

  5. (三)ActiveMQ之发布- 订阅消息模式实现

    一.概念 发布者/订阅者模型支持向一个特定的消息主题发布消息.0或多个订阅者可能对接收来自特定消息主题的消息感兴趣.在这种模型下,发布者和订阅者彼此不知道对方.这种模式好比是匿名公告板.这种模式被概括 ...

  6. JS 设计模式八 -- 发布订阅者模式

    概念 发布---订阅模式又叫观察者模式,它定义了对象间的一种一对多(一个发布,多个观察)的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知. 优点 1 ...

  7. 学习javascript设计模式之发布-订阅(观察者)模式

    1.发布-订阅模式又叫观察者模式,它定义对象之间一种一对多的依赖关系. 2.如何实现发布-订阅模式 2-1.首先指定好发布者 2-2.给发布者添加一个缓冲列表,用户存放回调函数以便通知订阅者 2-3. ...

  8. ionic3 发布订阅者模式实现

    在ionic3 中实现订阅发布模式,需要用到Events. Events下面有三个方法 events.subscribe()  订阅 events.publish()  发布 events.unsub ...

  9. 把酒言欢话聊天,基于Vue3.0+Tornado6.1+Redis发布订阅(pubsub)模式打造异步非阻塞(aioredis)实时(websocket)通信聊天系统

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_202 "表达欲"是人类成长史上的强大"源动力",恩格斯早就直截了当地指出,处在蒙昧时代即低 ...

随机推荐

  1. 扩展 ajaxupload.js ,支持客户端判断上传文件的大小

    onSubmit: function(file, extension){}, 修改为 onSubmit: function(file, extension, size){}, if (! (setti ...

  2. 区别 new function(){} 和 function(){}()

    只要 new 表达式之后的 constructor 返回(return)一个引用对象(数组,对象,函数等),都将覆盖new创建的匿名对象,如果返回(return)一个原始类型(无 return 时其实 ...

  3. iOS炫酷动画图案、多种选择器、网络测速、滑动卡片效果等源码

    iOS精选源码 对网络进行测速 自实现大标题,配合原生骨架屏demo 简单方便的pickerVIew记录数据 LZPickerView 科技风绘制组件,简单快速"画"出炫酷图案 R ...

  4. 用C#实现一个百度万年历

    目录 背景 实现步骤 关键点 结束语 背景 命理学是对人生命运规律的探索,以人的各式各样的数字(出生年月日.姓名笔划等)来推测人的性格与命运并占卜推测未来会发生的事情.古今中外都有相关方面的理论,中国 ...

  5. bug宝典linux篇 LC_CTYPE: cannot change locale (en_US.UTF-8): No such file or directory(转)

    升级glibc库后,使用xShell登录linux,提示: Connecting to ... Connection established. To escape to local shell, pr ...

  6. cs231n spring 2017 lecture4 Introduction to Neural Networks

    1. Backpropagation:沿着computational graph利用链式法则求导.每个神经元有两个输入x.y,一个输出z,好多层这种神经元连接起来,这时候已知∂L/∂z,可以求出∂L/ ...

  7. 用VS2013进行调试

    首先新建一个简单的C++程序 打开VS2013-文件-新建-项目-选择Win32 控制台程序 添加-新建项-选择C++源文件 编写如下代码 #include<iostream> using ...

  8. Holer一款局域网服务器代理到公网的内网映射工具

    Holer简介 Holer是一个将局域网服务器代理到公网的内网映射工具,支持转发基于TCP协议的报文. 相关链接 开源地址:https://github.com/Wisdom-Projects/hol ...

  9. js寄生组合式继承

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. JS截取字符串方法集合

    使用 substring()或者slice()   函数:split() 功能:使用一个指定的分隔符把一个字符串分割存储到数组 例子: str="jpg|bmp|gif|ico|png&qu ...