范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

发布订阅模式与观察者模式

  背景
  设计模式并非是软件开发的专业术语,实际上,"模式"最早诞生于建筑学。
  设计模式的定义是:在面向对象软件设计过程中针对特定问题的简洁而优雅的解决方案。通俗一点说,设计模式是在某种场合下对某个问题的一种解决方案。如果再通俗一点说,设计模式就是给面向对象软件开发中的一些好的设计取个名字。
  这些"好的设计"并不是谁发明的,而是早已存在于软件开发中。一个稍有经验的程序员也许在不知不觉中数次使用过这些设计模式。GoF(Gang of Four--四人组,《设计模式》几位作者)最大的功绩是把这些"好的设计"从浩瀚的面向对象世界中挑选出来,并且给予它们一个好听又好记的名字。
  设计模式并不直接用来完成代码的编写,而是描述在各种不同情况下,要怎么解决问题的一种方案,他不是一个死的机制,他是一种思想,一种写代码的形式。每种语言对于各种设计模式都有他们自己的实现方式,对于某些设计模式来说,可能在某些语言下并不适用,比如工厂方法模式对于javascript。模式应该用在正确的地方。而哪些才算正确的地方,只有在我们深刻理解了模式的意图之后,再结合项目的实际场景才会知道…
  模式的社区一直在发展。GoF在1995年提出了23种设计模式,但模式不仅仅局限于这23种,后面增加到了24种。在这20多年的时间里,也许有更多的模式已经被人发现并总结了出来,比如一些JavaScript 图书中会提到模块模式、沙箱模式等。这些"模式"能否被世人公认并流传下来,还有待时间验证。观察者模式(Observer Pattern)
  观察者模式定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知,并自动更新。观察者模式属于行为型模式,行为型模式关注的是对象之间的通讯,观察者模式就是观察者和被观察者之间的通讯。
  观察者模式有一个别名叫"发布-订阅模式",或者说是"订阅-发布模式",订阅者和订阅目标是联系在一起的,当订阅目标发生改变时,逐个通知订阅者。我们可以用报纸期刊的订阅来形象的说明,当你订阅了一份报纸,每天都会有一份最新的报纸送到你手上,有多少人订阅报纸,报社就会发多少份报纸,报社和订报纸的客户就是上面文章开头所说的"一对多"的依赖关系。发布订阅模式(Pub-Sub Pattern)
  其实24种基本的设计模式中并没有发布订阅模式,上面也说了,他只是观察者模式的一个别称。
  但是经过时间的沉淀,似乎他已经强大了起来,已经独立于观察者模式,成为另外一种不同的设计模式。
  在现在的发布订阅模式中,称为发布者的消息发送者不会将消息直接发送给订阅者,这意味着发布者和订阅者不知道彼此的存在。在发布者和订阅者之间存在第三个组件,称为消息代理或调度中心或中间件,它维持着发布者和订阅者之间的联系,过滤所有发布者传入的消息并相应地分发它们给订阅者。
  举一个例子,你在微博上关注了A,同时其他很多人也关注了A,那么当A发布动态的时候,微博就会为你们推送这条动态。A就是发布者,你是订阅者,微博就是调度中心,你和A是没有直接的消息往来的,全是通过微博来协调的(你的关注,A的发布动态)。观察者模式和发布订阅模式有什么区别?
  我们先来看下这两个模式的实现结构:
  观察者模式:观察者(Observer)直接订阅(Subscribe)主题(Subject),而当主题被激活的时候,会触发(Fire Event)观察者里的事件。
  发布订阅模式:订阅者(Subscriber)把自己想订阅的事件注册(Subscribe)到调度中心(Topic),当发布者(Publisher)发布该事件(Publish topic)到调度中心,也就是该事件触发时,由调度中心统一调度(Fire Event)订阅者注册到调度中心的处理代码。
  我们再来看下这两个模式的代码案例:(猎人发布与订阅任务)
  观察者模式: //有一家猎人工会,其中每个猎人都具有发布任务(publish),订阅任务(subscribe)的功能
  //他们都有一个订阅列表来记录谁订阅了自己
  //定义一个猎人类
  //包括姓名,级别,订阅列表
  function Hunter(name, level){
  this.name = name
  this.level = level
  this.list = []
  }
  Hunter.prototype.publish = function (money){
  console.log(this.level + "猎人" + this.name + "寻求帮助")
  this.list.forEach(function(item, index){
  item(money)
  })
  }
  Hunter.prototype.subscribe = function (targrt, fn){
  console.log(this.level + "猎人" + this.name + "订阅了" + targrt.name)
  targrt.list.push(fn)
  }
  //猎人工会走来了几个猎人
  let hunterMing = new Hunter("小明", "黄金")
  let hunterJin = new Hunter("小金", "白银")
  let hunterZhang = new Hunter("小张", "黄金")
  let hunterPeter = new Hunter("Peter", "青铜")
  //Peter等级较低,可能需要帮助,所以小明,小金,小张都订阅了Peter
  hunterMing.subscribe(hunterPeter, function(money){
  console.log("小明表示:" + (money > 200 ? "" : "暂时很忙,不能") + "给予帮助")
  })
  hunterJin.subscribe(hunterPeter, function(){
  console.log("小金表示:给予帮助")
  })
  hunterZhang.subscribe(hunterPeter, function(){
  console.log("小金表示:给予帮助")
  })
  //Peter遇到困难,赏金198寻求帮助
  hunterPeter.publish(198)
  //猎人们(观察者)关联他们感兴趣的猎人(目标对象),如Peter,当Peter有困难时,会自动通知给他们(观察者)
  发布订阅模式: //定义一家猎人工会
  //主要功能包括任务发布大厅(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 hunterMing = new Hunter("小明", "黄金")
  let hunterJin = new Hunter("小金", "白银")
  let hunterZhang = new Hunter("小张", "黄金")
  let hunterPeter = 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)
  //猎人们发布(发布者)或订阅(观察者/订阅者)任务都是通过猎人工会(调度中心)关联起来的,他们没有直接的交流。
  观察者模式和发布订阅模式最大的区别就是发布订阅模式有个事件调度中心。
  观察者模式由具体目标调度,每个被订阅的目标里面都需要有对观察者的处理,这种处理方式比较直接粗暴,但是会造成代码的冗余。
  而发布订阅模式中统一由调度中心进行处理,订阅者和发布者互不干扰,消除了发布者和订阅者之间的依赖。这样一方面实现了解耦,还有就是可以实现更细粒度的一些控制。比如发布者发布了很多消息,但是不想所有的订阅者都接收到,就可以在调度中心做一些处理,类似于权限控制之类的。还可以做一些节流操作。观察者模式是不是发布订阅模式
  网上关于这个问题的回答,出现了两极分化,有认为发布订阅模式就是观察者模式的,也有认为观察者模式和发布订阅模式是真不一样的。
  其实我不知道发布订阅模式是不是观察者模式,就像我不知道辨别模式的关键是设计意图还是设计结构(理念),虽然《JavaScript设计模式与开发实践》一书中说了分辨模式的关键是意图而不是结构。
  如果以结构来分辨模式,发布订阅模式相比观察者模式多了一个中间件订阅器,所以发布订阅模式是不同于观察者模式的;如果以意图来分辨模式,他们都是实现了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知,并自动更新,那么他们就是同一种模式,发布订阅模式是在观察者模式的基础上做的优化升级。
  不过,不管他们是不是同一个设计模式,他们的实现方式确实有差别,我们在使用的时候应该根据场景来判断选择哪个。

传祺GS4PLUS加量不加价,2。0T车型仅需14。6万就在5月31日,广汽传祺官方正式宣布传祺GS4PLUS于杭州工厂下线生产并接受预售,将于6月30日正式上市销售。新车GS4PLUS将定位A级SUV,共提供三款车型可选项,其价格为1海马汽车摘帽后剑走偏锋发力氢能源,能成功翻身吗?5月26日,海马汽车股份有限公司宣布停牌一日。其公司发布公告宣称,自5月27日开市起恢复交易,撤销其他风险警示,证券简称由ST海马变更为海马汽车,股票交易价格的日涨跌幅限制由5变为OPPO发布三款概念产品两大技术系统,布局未来科技科技创新一直是企业发展的硬道理,11月17日,OPPO在深圳举办了OPPO未来科技大会2020,在本次大会上,OPPO提出了科技为人,以善天下的品牌信仰。以致善式创新为选择,通过3全年净利润737万元,奇瑞汽车单车利润仅为丰田的千分之一不久前,安徽芜湖市建设投资有限公司发布了债券2020年年度报告。据报告显示,奇瑞汽车股份有限公司2020年累计汽车销量高达44。9万辆,营收为347。62亿元,相比于2019年有了50个漏光纹理ps笔刷50个漏光纹理ps笔刷分享给大家,这是一套适用于AdobePhotoshop的特效笔刷合集,可以帮助用户制造各种各样的黑色混沌墨水纹理图案。专业电影制作或者业余爱好人士都非常适用。不用好运气也可以躺赢,余额宝1天帮赚1个亿今年,是我们见证许多梦想实现的一年,广大网友的梦想不仅要追求赢,还要追求躺赢。比如做女团里的杨超越,锦鲤里的信小呆。然鹅,咸鱼毕竟不好翻身,不是所有人都有主角光环傍身,也不是所有人名门修谱为什么国人如今依旧坚持修家谱?家谱新修人们说到姓氏,会很容易想到家族,而从家族,又会很自然地想到家谱。家谱,历来就是我国姓氏学中的重要内容之一。我国向来重视对自己过去历史的回顾与反思,编撰有各种各样的一家之史一名门修谱生儿子才能续家谱?这种想法大错特错李氏族谱中国自周朝一代,从原始的自然崇拜转为祖先崇拜,在中国人的观念中早已深深地刻上了传承二字。而国人传承,记录得最为真实的就是家谱。家谱文化从起始到现在经历过许多的变革,其中重男数万套未加验证保护的数据库暴露在外云服务器网站建站域名注册虚拟主机企业邮箱新网知名的互联网基础应用服务提供商云数据库资讯数据库技术发展已达半个世纪之久,而云时代开始以后,我们可以从全新的视角审视数据库等基础技术的过怎么做外贸网站推广?5个超好用方法推荐新网建站资讯外贸企业面对的是海外的客户,因为距离的问题,信息不对称,让海外客户认识你的品牌与产品,就比让国内客户认识你的品牌与产品难许多。怎么做外贸网站推广?这是一个让很多外贸se和府餐饮完成近8亿元E轮融资,品牌域名怎么样?新网域名资讯近日,国内餐饮头部品牌和府餐饮宣布完成近8亿元E轮融资。本轮投资由CMC资本领投,新股东众为资本老股东腾讯投资LongforCapital跟投。这也是今年以来,国内连锁
华为7000名老员工集体辞职,任正非支持,华为没终身成就这一说华为是我国手机行业的龙头企业,而且在世界手机市场也有很大的竞争力。要知道华为并不是手机发家的,但是在手机行业的成就也是巨大的,近年来华为受到美国打压和制裁是人尽皆知的事情,但是就在翰飞科技元宇宙助推虚拟人又一火爆的万亿赛道一元宇宙助推虚拟人赛道变热什么是虚拟人?顾名思义,虚拟人是一个与现实人相对应的概念,即不存在于现实世界,只存在于虚拟世界的人。从中国第一个原创虚拟学生清华大学的华智冰,到小红书潮流coupang跨境电商盈利模式跨境店的模式就是自发货模式,这种模式不用店主预先囤货,可以把国内批发网站的货品搬到韩国网店上卖给韩国人,要知道韩国的劳动力成本是非常贵的,这也导致了他们的商品价值都很高昂,咱们中国什么是区块链?不是比特币进化慢,而是我们进化慢自从区块链(blockchain)这个词被从比特币中抽象出来之后,整个业内就弥漫着一种奇特的意识形态叙事(ideologicalnarrative)。这个叙事是这样的比特币是一架又元宇宙发展规划1数字家庭以智能家电为主,家电系列万物互联,华为的鸿蒙系统比较具有代表性。2数字城市道路交通数字化,微型交通城市服务系统,实时服务系统。3数字地球气象技术有较大发展,地球的各种天气外卖行业的最终结果是怎么样呢?中国外卖行业的最终结果沦落为廉价餐饮的销售平台。首先,现在外卖平台的配送费都不高,基本在每单6元钱左右。配送费不高的原因在于,消费者的消费能力有限。如果你点一个30元的餐饮配送需要价值120万元一针的抗癌药未进入医保目录谈判环节22岁董明珠女秘书回应走红今天的热点新闻你都知道了吗?社会类1国家邮政局双11当日快递包裹量6。96亿件创新高中国国家邮政局监测数据显示,11月1日至11日,全国邮政快递企业共处理快件47。76亿件,同比增小米手机便签里的内容如何导出到vivo里小米手机和Vivo手机上都有自带的便签工具,可以在各自品牌的手机上使用,但vivo手机上无法直接安装小米手机自带便签使用。除了手机自带便签,两个品牌的手机上也可以同时安装第三方便签搞定家用轻办公和游戏竞技,年底选这两台宁美主机准没错又到年底,相信不少小伙伴都有萌生出给自己换一台新电脑主机的想法。不过,这对于不熟悉电脑硬件的小白用户而言,一方面需要重头开始学习装机,另一方面需要根据自己的需求和预算挑选硬件,实在大家都在讲大数据,大数据是什么呢?很高兴能够看到和回答这个问题!如今这个时代,大数据,云计算这些热门概念是人们茶余饭后议论的热点话题,然而很多人还是搞不清楚什么是大数据。今天,每日精彩科技将根据自己的经验回答这个问中国电信公布5G手机5G性能数据小米Redmi全价位第一手机中国新闻11月13日,小米集团高级副总裁手机部总裁曾学忠宣布,在2021国际数字科技展暨天翼智能生态博览会上,中国电信公布了5G手机的5G性能评测数据,小米和Redmi包揽全价