觀察者模式 vs 發佈訂閱模式

原文地址:zhuanlan.zhihu.com/p/51357583
做者:柳樹面試

有一回面試,面試官問:編程

觀察者模式,和發佈訂閱模式,有什麼區別?設計模式

我腦海中馬上閃現了《Head First設計模式》裏講的:app

Publishers + Subscribers = Observer Pattern設計

「哼哼,我知道答案了,兄dei!」,我心裏無比雞凍。code

「它們是同樣的。」,我故做鎮定,嘴角露出一絲微笑,彷彿下一秒鐘面試官就會給我發offer。cdn

面試官也笑了,「不,它們不同」。server

而後我就:中間件

So, 爲何我錯了?觀察者模式(Observer pattern),和發佈訂閱模式(Publish–subscribe pattern),到底有什麼不一樣?對象

觀察者模式

所謂觀察者模式,其實就是爲了實現鬆耦合(loosely coupled)

用《Head First設計模式》裏的氣象站爲例子,每當氣象測量數據有更新,changed()方法就會被調用,因而咱們能夠在changed()方法裏面,更新氣象儀器上的數據,好比溫度、氣壓等等。

可是這樣寫有個問題,就是若是之後咱們想在changed()方法被調用時,更新更多的信息,好比說溼度,那就要去修改changed()方法的代碼,這就是緊耦合的壞處。

怎麼解決呢?使用觀察者模式,面向接口編程,實現鬆耦合。

觀察者模式裏面,changed()方法所在的實例對象,就是被觀察者(Subject,或者叫Observable),它只需維護一套觀察者(Observer)的集合,這些Observer實現相同的接口,Subject只須要知道,通知Observer時,須要調用哪一個統一方法就行了:

這裏就不貼代碼了,網上已經有大量的資料。

發佈訂閱模式

大概不少人都和我同樣,以爲發佈訂閱模式裏的Publisher,就是觀察者模式裏的Subject,而Subscriber,就是Observer。Publisher變化時,就主動去通知Subscriber。

其實並非。

在發佈訂閱模式裏,發佈者,並不會直接通知訂閱者,換句話說,發佈者和訂閱者,彼此互不相識。

互不相識?那他們之間如何交流?

答案是,經過第三者,也就是在消息隊列裏面,咱們常說的經紀人Broker。

發佈者只需告訴Broker,我要發的消息,topic是AAA;

訂閱者只需告訴Broker,我要訂閱topic是AAA的消息;

因而,當Broker收到發佈者發過來消息,而且topic是AAA時,就會把消息推送給訂閱了topic是AAA的訂閱者。固然也有多是訂閱者本身過來拉取,看具體實現。

也就是說,發佈訂閱模式裏,發佈者和訂閱者,不是鬆耦合,而是徹底解耦的。

放一張極簡的圖,給你們對比一下這兩個模式的區別:

總結

從表面上看:

  • 觀察者模式裏,只有兩個角色 —— 觀察者 + 被觀察者
  • 而發佈訂閱模式裏,卻不單單隻有發佈者和訂閱者兩個角色,還有一個常常被咱們忽略的 —— 經紀人Broker

往更深層次講:

  • 觀察者和被觀察者,是鬆耦合的關係
  • 發佈者和訂閱者,則徹底不存在耦合

從使用層面上講:

  • 觀察者模式,多用於單個應用內部
  • 發佈訂閱模式,則更多的是一種跨應用的模式(cross-application pattern),好比咱們經常使用的消息中間件

最後,個人全部文字,都是對這篇文章的拙劣模仿:Observer vs Pub-Sub pattern

相關文章
相關標籤/搜索