成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

面試官:說說你對發布訂閱、觀察者模式的理解?區別?

開發 前端
觀察者模式定義了對象間的一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴于它的對象都將得到通知,并自動更新

[[433804]]

文末本文轉載自微信公眾號「JS每日一題」,作者灰灰 。轉載本文請聯系JS每日一題公眾號。

一、觀察者模式

觀察者模式定義了對象間的一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴于它的對象都將得到通知,并自動更新

觀察者模式屬于行為型模式,行為型模式關注的是對象之間的通訊,觀察者模式就是觀察者和被觀察者之間的通訊

例如生活中,我們可以用報紙期刊的訂閱來形象的說明,當你訂閱了一份報紙,每天都會有一份最新的報紙送到你手上,有多少人訂閱報紙,報社就會發多少份報紙

報社和訂報紙的客戶就形成了一對多的依賴關系

實現代碼如下:

被觀察者模式

  1. class Subject { 
  2.  
  3.   constructor() { 
  4.     this.observerList = []; 
  5.   } 
  6.  
  7.   addObserver(observer) { 
  8.     this.observerList.push(observer); 
  9.   } 
  10.  
  11.   removeObserver(observer) { 
  12.     const index = this.observerList.findIndex(o => o.name === observer.name); 
  13.     this.observerList.splice(index, 1); 
  14.   } 
  15.  
  16.   notifyObservers(message) { 
  17.     const observers = this.observeList; 
  18.     observers.forEach(observer => observer.notified(message)); 
  19.   } 
  20.  

觀察者:

  1. class Observer { 
  2.  
  3.   constructor(name, subject) { 
  4.     this.name = name
  5.     if (subject) { 
  6.       subject.addObserver(this); 
  7.     } 
  8.   } 
  9.  
  10.   notified(message) { 
  11.     console.log(this.name'got message', message); 
  12.   } 

使用代碼如下:

  1. const subject = new Subject(); 
  2. const observerA = new Observer('observerA', subject); 
  3. const observerB = new Observer('observerB'); 
  4. subject.addObserver(observerB); 
  5. subject.notifyObservers('Hello from subject'); 
  6. subject.removeObserver(observerA); 
  7. subject.notifyObservers('Hello again'); 

上述代碼中,觀察者主動申請加入被觀察者的列表,被觀察者主動將觀察者加入列表

二、發布訂閱模式

發布-訂閱是一種消息范式,消息的發送者(稱為發布者)不會將消息直接發送給特定的接收者(稱為訂閱者)。而是將發布的消息分為不同的類別,無需了解哪些訂閱者(如果有的話)可能存在

同樣的,訂閱者可以表達對一個或多個類別的興趣,只接收感興趣的消息,無需了解哪些發布者存在

實現代碼如下:

  1. class PubSub { 
  2.   constructor() { 
  3.     this.messages = {}; 
  4.     this.listeners = {}; 
  5.   } 
  6.   // 添加發布者 
  7.   publish(type, content) { 
  8.     const existContent = this.messages[type]; 
  9.     if (!existContent) { 
  10.       this.messages[type] = []; 
  11.     } 
  12.     this.messages[type].push(content); 
  13.   } 
  14.   // 添加訂閱者 
  15.   subscribe(type, cb) { 
  16.     const existListener = this.listeners[type]; 
  17.     if (!existListener) { 
  18.       this.listeners[type] = []; 
  19.     } 
  20.     this.listeners[type].push(cb); 
  21.   } 
  22.   // 通知 
  23.   notify(type) { 
  24.     const messages = this.messages[type]; 
  25.     const subscribers = this.listeners[type] || []; 
  26.     subscribers.forEach((cb, index) => cb(messages[index])); 
  27.   } 

發布者代碼如下:

  1. class Publisher { 
  2.   constructor(name, context) { 
  3.     this.name = name
  4.     this.context = context; 
  5.   } 
  6.   publish(type, content) { 
  7.     this.context.publish(type, content); 
  8.   } 

訂閱者代碼如下:

  1. class Subscriber { 
  2.   constructor(name, context) { 
  3.     this.name = name
  4.     this.context = context; 
  5.   } 
  6.   subscribe(type, cb) { 
  7.     this.context.subscribe(type, cb); 
  8.   } 

使用代碼如下:

  1. const TYPE_A = 'music'
  2. const TYPE_B = 'movie'
  3. const TYPE_C = 'novel'
  4.  
  5. const pubsub = new PubSub(); 
  6.  
  7. const publisherA = new Publisher('publisherA', pubsub); 
  8. publisherA.publish(TYPE_A, 'we are young'); 
  9. publisherA.publish(TYPE_B, 'the silicon valley'); 
  10. const publisherB = new Publisher('publisherB', pubsub); 
  11. publisherB.publish(TYPE_A, 'stronger'); 
  12. const publisherC = new Publisher('publisherC', pubsub); 
  13. publisherC.publish(TYPE_C, 'a brief history of time'); 
  14.  
  15. const subscriberA = new Subscriber('subscriberA', pubsub); 
  16. subscriberA.subscribe(TYPE_A, res => { 
  17.   console.log('subscriberA received', res) 
  18. }); 
  19. const subscriberB = new Subscriber('subscriberB', pubsub); 
  20. subscriberB.subscribe(TYPE_C, res => { 
  21.   console.log('subscriberB received', res) 
  22. }); 
  23. const subscriberC = new Subscriber('subscriberC', pubsub); 
  24. subscriberC.subscribe(TYPE_B, res => { 
  25.   console.log('subscriberC received', res) 
  26. }); 
  27.  
  28. pubsub.notify(TYPE_A); 
  29. pubsub.notify(TYPE_B); 
  30. pubsub.notify(TYPE_C); 

上述代碼,發布者和訂閱者需要通過發布訂閱中心進行關聯,發布者的發布動作和訂閱者的訂閱動作相互獨立,無需關注對方,消息派發由發布訂閱中心負責

三、區別

兩種設計模式思路是一樣的,舉個生活例子:

觀察者模式:某公司給自己員工發月餅發粽子,是由公司的行政部門發送的,這件事不適合交給第三方,原因是“公司”和“員工”是一個整體

發布-訂閱模式:某公司要給其他人發各種快遞,因為“公司”和“其他人”是獨立的,其唯一的橋梁是“快遞”,所以這件事適合交給第三方快遞公司解決

上述過程中,如果公司自己去管理快遞的配送,那公司就會變成一個快遞公司,業務繁雜難以管理,影響公司自身的主營業務,因此使用何種模式需要考慮什么情況兩者是需要耦合的

兩者區別如下圖:

在觀察者模式中,觀察者是知道Subject的,Subject一直保持對觀察者進行記錄。然而,在發布訂閱模式中,發布者和訂閱者不知道對方的存在。它們只有通過消息代理進行通信。

在發布訂閱模式中,組件是松散耦合的,正好和觀察者模式相反。

觀察者模式大多數時候是同步的,比如當事件觸發,Subject就會去調用觀察者的方法。而發布-訂閱模式大多數時候是異步的(使用消息隊列)

參考文獻

https://zh.wikipedia.org/zh-hans/%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F

https://zh.wikipedia.org/wiki/%E5%8F%91%E5%B8%83/%E8%AE%A2%E9%98%85

https://www.cnblogs.com/onepixel/p/10806891.html

 

https://juejin.cn/post/6978728619782701087

 

責任編輯:武曉燕 來源: JS每日一題
相關推薦

2020-12-09 05:18:17

面試觀察者訂閱模式

2021-11-25 10:18:42

RESTfulJava互聯網

2021-08-09 07:47:40

Git面試版本

2020-12-01 08:47:36

Java異常開發

2020-06-12 15:50:56

options前端服務器

2021-11-02 22:04:58

模式

2021-11-10 07:47:49

組合模式場景

2021-11-03 14:10:28

工廠模式場景

2021-11-05 07:47:56

代理模式對象

2021-11-09 08:51:13

模式命令面試

2021-08-19 08:36:22

Git ResetGit Revert版本

2021-11-11 16:37:05

模板模式方法

2021-11-22 23:50:59

責任鏈模式場景

2021-08-17 07:15:16

Git RebaseGit Merge面試

2021-09-16 07:52:18

算法應用場景

2021-10-15 09:53:12

工具

2019-05-10 10:50:04

Spring AOPJDK動態代理CGLIB動態代理

2021-09-07 08:33:27

JavaScript TypeScript 函數

2021-08-02 17:21:08

設計模式訂閱

2020-12-04 06:27:04

序列化面試官Java
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲视频免费在线观看 | 国产欧美一级 | 在线视频日韩 | 亚洲午夜精品视频 | 欧美激情欧美激情在线五月 | 中文字幕高清在线 | 亚洲福利精品 | 二区中文字幕 | 久久久久久免费毛片精品 | 欧美亚洲在线 | 国产在线一区二区三区 | 国产在线一区二区 | 国产小u女发育末成年 | 在线观看免费av网站 | 羞羞视频在线观看 | 在线一区二区三区 | 综合久久一区 | 日韩中文字幕 | 亚洲精品久久久久久久久久久 | 一级做a爰片性色毛片 | 午夜a区 | 亚洲福利网 | 亚洲精品久久久久久一区二区 | 久久久亚洲 | 99热在线观看精品 | 一级全黄视频 | 日本aaaa| 一级黄色裸片 | 新超碰97 | 午夜免费视频 | 日韩av成人| 人人人人干 | 国产视频久久久 | 日本久久综合网 | 成人在线中文字幕 | 日韩黄a| 国产精品久久久久久久午夜片 | 中文区中文字幕免费看 | 最新中文字幕 | 99久久久无码国产精品 | 国产一区日韩在线 |