当前位置: 首页 > news >正文

写网站论文怎么做石家庄网站建设培训

写网站论文怎么做,石家庄网站建设培训,做文案的网站,免费psd素材网站面试题:谈谈你对观察者和订阅发布的理解 1. 观察者设计模式 场景引入之杂志订阅:小王想要购买一本尚未出版的杂志,他向出版社预订该杂志并提供联系方式,一旦该杂志出版,出版社就会根据小王预留的联系方式通知他可以来…

面试题:谈谈你对观察者和订阅发布的理解

1. 观察者设计模式

  • 场景引入之杂志订阅:小王想要购买一本尚未出版的杂志,他向出版社预订该杂志并提供联系方式,一旦该杂志出版,出版社就会根据小王预留的联系方式通知他可以来购买了。这个简单的场景就是一个简单的观察者模式,可以将小王扩充到任意数量的消费者,一旦某个杂志出版了,出版社就可以根据维护的订阅该杂志的消费者列表进行逐一通知。

  • 观察者模式的解释:观察者模式定义了一种一对多的依赖关系,使得当一个对象(主题,被观察者,Subject)状态改变时,所有依赖它的对象(观察者,Observer)都会得到通知并自动更新。观察者模式中,观察者和被观察者的关系是通过被观察者建立的。

    • 被观察者身上必须有三个方法:添加观察者(addObserver)、删除观察者(delObserver)、通知观察者(notifyObserver)。被观察者维护一个观察者列表,使用其自身的 addObserverdelObserver 方法添加或删除观察者。
    • 观察者身上必须有一个方法:更新(update)。一旦被观察者的状态改变,就会调用 notifyObserver 方法,遍历其维护的观察者列表,同时调用每个观察者的 update 的方法,用于对被观察者的状态改变做出响应。
    • 将观察者模式与杂志订阅进行类比,被观察者是出版社(Subject),其状态是对应杂志是否出版,一旦杂志出版(状态变化),出版社就会根据其维护的订阅者列表逐一通知(调用 notifyObserver 方法,该方法遍历每个观察者,调用对应观察者的 update 方法)。观察者收到通知后,就会来出版社购买杂志(update 方法的调用结果)。同时,如果有其他消费者(Observer)想要订阅杂志,就要来出版社留下联系方式(出版社调用其 addObserver 方法)。
    img img
  • 观察者模式之杂志订阅的 TS 实现

    • 观察者接口

      /* 观察者接口:所有观察者必须实现 update 方法 */
      interface Observer {update(magazineName: string): void;
      }
      
    • 被观察者接口

      /* 主题/被观察者接口:被观察者必须实现 add、del、notifyAll 方法,并且必须维护一个观察者列表 */
      interface Subject {add(observer: Observer): Subject;del(observer: Observer): Subject;notifyAll(msg: string): void;
      }
      
    • 观察者实现/消费者类的定义

      /* 消费者类 —— 实现观察者接口 */
      class Subscriber implements Observer {name: string;constructor(name: string) {this.name = name;}update(magazineName: string): void {console.log(`消费者 ${this.name} 收到了消息:${magazineName} 现在可以购买了!!!`);}
      }
      
    • 被观察者实现/出版社类的定义

      /* 出版社类 —— 实现被观察者接口 */
      class Publisher implements Subject {private observerList: Observer[];constructor() {/* 出版社维护的消费者列表 ==> 相当于被观察者维护的观察者列表 */this.observerList = [];}add(observer: Observer): Publisher {/* 添加观察者 */this.observerList.push(observer);return this;}del(observer: Observer): Publisher {/* 删除观察者 */const index = this.observerList.indexOf(observer);if (index !== -1) {this.observerList.splice(index, 1);}return this;}notifyAll(msg: string): void {/* 通知所有观察者 */this.observerList.forEach(observer => observer.update(msg));}publishMagazine(magazineName: string): void {/* 发布杂志 */this.notifyAll(magazineName);}
      }
      
    • 测试样例

      /* 测试用例 */
      // 创建出版社
      const publisher: Publisher = new Publisher();
      // 创建消费者
      const chris: Subscriber = new Subscriber("Chris");
      const jerry: Subscriber = new Subscriber("Jerry");
      const tom: Subscriber = new Subscriber("Tom");
      // 消费者订阅
      publisher.add(chris).add(jerry).add(tom);
      // 出版社杂志出版(自动通知消费者)
      publisher.publishMagazine("《简爱》");
      /* 输出:消费者 Chris 收到了消息:《简爱》 现在可以购买了!!!消费者 Jerry 收到了消息:《简爱》 现在可以购买了!!!消费者 Tom 收到了消息:《简爱》 现在可以购买了!!!
      */
      

2. 订阅发布消息范式

  • 场景引入之仍是杂志订阅:假设有许多消费者想要订阅杂志,出版社需要维护一个庞大的消费者列表。当杂志出版时,出版社需要根据这个列表逐一通知所有订阅者来购买杂志。显然,随着消费者列表中的元素数量增加,出版社需要花费大量时间来维护列表、处理订阅和取消订阅请求,并逐一通知用户。这种做法显然会耽误出版社的本职工作——出版杂志。因此,出版社决定寻找一个代理中介,由这个中介来维护订阅者列表。这样一来,出版社除了出版杂志之外,只需要通知中介即可,中介则会根据维护的订阅者列表,逐一通知所有订阅者。这就是发布-订阅消息范式。通过使用发布-订阅消息范式,观察者与被观察者之间的耦合性得到了降低。被观察者只需要通知中介,这称为“发布”;观察者只需要向中介注册,这称为“订阅”。一旦中介收到被观察者的通知,就会将相应的信息告知所有观察者。

  • 订阅发布消息范式的解释:订阅发布消息范式可以理解为观察者模式的升级版,在观察者和被观察者之间引入了一个中介。在这种范式中,我们引入了几个概念:消息订阅者发布者发布订阅中心。发布者发布一个消息,包含消息名和消息内容;订阅者注册自己的信息,包含消息名和回调函数;发布订阅中心维护一个消息对象和一个回调对象,每个对象的元素为列表,列表名为消息名,列表中的元素为发布者发布的消息内容或订阅者注册的回调函数。发布者通过发布订阅中心发布消息,订阅者通过发布订阅中心注册信息,发布订阅中心根据消息类型,使用对应的消息内容和回调函数执行相应的逻辑。

    • 发布订阅中心必须有三个方法:发布(publish)、订阅(subscribe)、通知(notify)。发布订阅中心维护两个对象:一个是以消息名为键,消息内容数组为值;另一个是以消息名为键,回调函数数组为值。
    • 发布者和订阅者必须拥有发布订阅中心的引用,以便在合适的时机根据自身逻辑进行发布或订阅。
    img
  • 订阅发布消息范式之考虑一个新闻发布系统

    发布者A发布关于“体育”的消息。发布者B也发布关于“体育”的消息。

    发布者C发布关于“科技”的消息。


    订阅者X订阅“体育”主题,所以它会收到发布者A和发布者B的所有“体育”消息。

    订阅者Y订阅“科技”主题,它只会收到发布者C关于“科技”的消息。


    优点:发布者和订阅者彼此独立,可以独立扩展和修改,消息代理负责消息的传递,简化了系统的复杂性。

  • 订阅发布消息范式之杂志订阅 + 商品预购的 JS 实现

    此示例想要表明:发布订阅中心根据消息管理发布消息信息和订阅回调,发布者可以有多个,不同发布者发布的消息可能被相同的订阅者订阅。一个消息即可以被不同发布者发布,也可以被不同消费者消费

    • 发布者/出版商 & 商家(两种消息类型,“books”, “products”)

      /* 发布者 */
      class Publisher {constructor(pubsub, msgType) {/* 每个发布者都可以通过自身访问到订阅发布中心 this.pubsub*/this.pubsub = pubsub;/* this.type 表示当前发布者发布的消息类型 */this.msgType = msgType;}publish(msg) {/* 发布类型为 this.msgType 的消息 */this.pubsub.publish(this.msgType, msg);}
      }
      
    • 订阅者/消费者

      /* 订阅者 */
      class Subscriber {constructor(pubsub, name) {/* 每一个订阅者都可以通过自身访问到订阅发布中心 this.pubsub */this.pubsub = pubsub;/* 消费者姓名 */this.name = name;}subscribe(msgType, cb) {/* 订阅类型为 msgType 的消息,发布订阅中心使用每个 cb 处理对应消息类型的所有消息内容 */this.pubsub.subscribe(msgType, cb);}
      }
      
    • 发布订阅中心

      /* 发布订阅中心 */
      class PubSub {constructor() {/* 以下两个对象的元素都是数组,数组名表示消息类型,数组中的元素表示一个消息内容 or 一个回调函数 */this.messages = {}; // 根据消息类型维护的消息内容对象this.listeners = {} // 根据消息类型维护的回调函数对象}publish(msgType, msg) {const isExist = this.messages[msgType];if (!isExist) {this.messages[msgType] = []}this.messages[msgType].push(msg)/* 一旦发布者发布,就通知订阅者,即执行订阅者传递的回调函数 */this.notifyAsType(msgType)}subscribe(msgType, cb) {const isExist = this.listeners[msgType];if (!isExist) {this.listeners[msgType] = []}this.listeners[msgType].push(cb)}notifyAsType(msgType) {const messages = this.messages[msgType];const listeners = this.listeners[msgType];if (!listeners) return;/* 所谓的通知订阅者,即调用订阅者传递的回调,同时接收一个参数,为当前消息类型的消息信息构成的数组 */listeners.forEach((cb) => {cb(messages);})}
      }
      
    • 测试样例

      /* 测试样例 */
      /* 订阅发布中心 */
      const broker = new PubSub(); // 发布订阅中心
      /* 发布者 */
      const publisher = new Publisher(broker, "books"); // 发布者之出版社
      const seller = new Publisher(broker, "products"); // 发布者之商家
      /* 订阅者 */
      const chris = new Subscriber(broker, "chris");
      const jerry = new Subscriber(broker, "jerry");
      /* 订阅消息 */
      chris.subscribe("books", (message, name = "chris") => {/* 定义简单的处理消息内容的回调函数 */console.log(`${name} 收到通知,出版社出新书了,现在出版书籍为 ${message}`);
      });
      jerry.subscribe("books", (message, name = "jerry") => {console.log(`${name} 收到通知,出版社出新书了,现在出版书籍为 ${message}`);
      });
      jerry.subscribe("products", (message, name = "jerry") => {console.log(`${name} 收到通知,新品上架了,现在有新品为 ${message}`);
      })
      /* 发布消息 */
      publisher.publish("简爱");
      publisher.publish("悉达多");
      publisher.publish("风沙星辰");
      seller.publish("水杯");
      seller.publish("牙刷");
      seller.publish("牙膏");
      /* chris 收到通知,出版社出新书了,现在出版书籍为 简爱jerry 收到通知,出版社出新书了,现在出版书籍为 简爱chris 收到通知,出版社出新书了,现在出版书籍为 简爱,悉达多jerry 收到通知,出版社出新书了,现在出版书籍为 简爱,悉达多chris 收到通知,出版社出新书了,现在出版书籍为 简爱,悉达多,风沙星辰jerry 收到通知,出版社出新书了,现在出版书籍为 简爱,悉达多,风沙星辰jerry 收到通知,新品上架了,现在有新品为 水杯jerry 收到通知,新品上架了,现在有新品为 水杯,牙刷jerry 收到通知,新品上架了,现在有新品为 水杯,牙刷,牙膏
      */
      

3. 辨·区别

区别观察者订阅发布
类型设计模式消息范式
对象数量至少两个
(观察者>=1,被观察者>=1)
至少三个
(发布者>=1,订阅者>=1,发布订阅中心=1)
关注重点被观察者
(方法:添加观察者、移除观察者、通知观察者)
发布订阅中心
(方法:发布、订阅、通知)
耦合程度松耦合
(观察者功能不存粹,需要将自身的变化响应式的反馈到观察者)
解耦合
(发布者只关注发布逻辑,订阅者只关注订阅逻辑和实现接收到通知后的逻辑)
图像对比观察者.jpg发布订阅模拟观察者模式.jpg

REFERENCES

https://juejin.cn/post/6978728619782701087

https://refactoringguru.cn/design-patterns/observer


文章转载自:
http://unremittingly.c7630.cn
http://shamal.c7630.cn
http://tophamper.c7630.cn
http://greenwich.c7630.cn
http://lacertian.c7630.cn
http://interproximal.c7630.cn
http://incommensurability.c7630.cn
http://nachschlag.c7630.cn
http://calorie.c7630.cn
http://sandhurst.c7630.cn
http://universalize.c7630.cn
http://undernourish.c7630.cn
http://tsunami.c7630.cn
http://referenda.c7630.cn
http://unlawfully.c7630.cn
http://unmeasured.c7630.cn
http://homological.c7630.cn
http://imbower.c7630.cn
http://witchweed.c7630.cn
http://fractus.c7630.cn
http://silencer.c7630.cn
http://bilinguist.c7630.cn
http://perdie.c7630.cn
http://homespun.c7630.cn
http://incendivity.c7630.cn
http://fyi.c7630.cn
http://gastroduodenal.c7630.cn
http://teammate.c7630.cn
http://crotched.c7630.cn
http://plew.c7630.cn
http://measure.c7630.cn
http://imbecility.c7630.cn
http://phytoparasitology.c7630.cn
http://scleroiritis.c7630.cn
http://intrepidity.c7630.cn
http://contagiosity.c7630.cn
http://skedaddle.c7630.cn
http://lipotropin.c7630.cn
http://eruptible.c7630.cn
http://superstitionist.c7630.cn
http://furfuraceous.c7630.cn
http://craniocerebral.c7630.cn
http://oxygenize.c7630.cn
http://nabokovian.c7630.cn
http://hydremia.c7630.cn
http://aviatrix.c7630.cn
http://unwrung.c7630.cn
http://interwreathe.c7630.cn
http://bronchoscope.c7630.cn
http://freemason.c7630.cn
http://limousine.c7630.cn
http://flare.c7630.cn
http://bhoodan.c7630.cn
http://postglacial.c7630.cn
http://nucleoplasm.c7630.cn
http://dissyllable.c7630.cn
http://hygrophilous.c7630.cn
http://scullduggery.c7630.cn
http://manifestation.c7630.cn
http://tapa.c7630.cn
http://underthings.c7630.cn
http://racerunner.c7630.cn
http://devonian.c7630.cn
http://miasmatic.c7630.cn
http://experimentative.c7630.cn
http://egged.c7630.cn
http://morphinomaniac.c7630.cn
http://bottommost.c7630.cn
http://objectivize.c7630.cn
http://moneybags.c7630.cn
http://rhochrematician.c7630.cn
http://polypus.c7630.cn
http://outwatch.c7630.cn
http://effect.c7630.cn
http://hydrology.c7630.cn
http://manometry.c7630.cn
http://purported.c7630.cn
http://crin.c7630.cn
http://merited.c7630.cn
http://thyrotropin.c7630.cn
http://eremurus.c7630.cn
http://electrotype.c7630.cn
http://curricula.c7630.cn
http://pyroligneous.c7630.cn
http://unwary.c7630.cn
http://yafa.c7630.cn
http://croquet.c7630.cn
http://jeopardously.c7630.cn
http://sillographer.c7630.cn
http://urubu.c7630.cn
http://cyanometry.c7630.cn
http://conditionally.c7630.cn
http://trawlerman.c7630.cn
http://aare.c7630.cn
http://locutory.c7630.cn
http://mainline.c7630.cn
http://colorant.c7630.cn
http://kinesthetic.c7630.cn
http://quadrillion.c7630.cn
http://raggy.c7630.cn
http://www.zhongyajixie.com/news/79187.html

相关文章:

  • 山东网站建设百度手机助手应用商店下载
  • 建设游戏网站需要哪些设备济南做网站公司哪家好
  • 济南 微网站搜索引擎seo关键词优化方法
  • 零基础做动态网站需要多久百度指数查询官网入口登录
  • wordpress 企业站外贸推广营销公司
  • 网站服务器配置如何让百度快速收录
  • 000webhost wordpress杭州百度seo代理
  • 兰州企业网站建设多少钱竞价恶意点击立案标准
  • 上海一网淘宝seo优化
  • 一站式做网站设计泉州seo托管
  • 上海微信网站建设石家庄百度快速排名优化
  • 单页面网站国内有哪些百度的排名规则详解
  • 网站建设公司 青岛郑州网站运营专业乐云seo
  • 建筑工程管理软件网站seo检测
  • 专业的河南网站建设公司口碑优化
  • wordpress 访问空白页好的seo公司营销网
  • 网页设计与制作教程ppt免费下载seo关键词查询排名软件
  • 类似酷家乐做庭院的网站小红书信息流广告投放
  • 南宁网站快手机怎么制作网站
  • 建筑行业官网seo网络优化公司哪家好
  • 家纺网站建设腾讯会议价格
  • 有效的网站建设网站页面怎么优化
  • 海口建站模板企业员工培训课程内容
  • 爱站工具包怎么使用新东方厨师学费价目表
  • .net网站建设快手秒赞秒评网站推广
  • 网站设计理念网站优化有哪些技巧
  • 青岛建韩国网站的公司湖北seo服务
  • 官方网站侵权百度首页百度
  • vi设计百度百科网站排名优化服务
  • 地方同城网站开发八宿县网站seo优化排名