观察者模式VS发布-订阅模式
前言
觀察者模式的大名,想必各位看官早已有所耳聞。從我們現實生活來說,微信公眾號訂閱、醫院掛號叫號等都屬于它的實際應用。在程序世界中,它是一種用于將代碼解耦的設計模式,如果你想掌握并理解這種設計模式,今天就和我一起來探究它的奧秘之處吧!
觀察者模式
在前文講述事件機制時,我們其實已經提到了觀察者模式。觀察者模式事實上實現了一種通訊機制,也就是觀察目標對觀察者進行通知的機制。在基于低耦合的設計前提下,觀察者無需直接調用觀察目標的內部方法或屬性獲取通知,而是使用“訂閱”的方式獲取通知,大體的流程圖如下:
結合實際開發例子來說,在C#中我們只需要定義相應的委托和事件,即可實現觀察者模式的使用,詳細使用方法可以參考我之前的文章內容:再談C#中的委托和事件,在此不再贅述。
但在其他語言中,例如Java,本身未提供類似委托或事件的機制進行回調,因此在實現方面會略微繁瑣一些,相關類圖如下:
在這種實現方式中,我們需要對觀察目標,也就是發布主題進行一個抽象,即圖中的Subject,用于提供保存觀察者的集合(圖中的ArrayList),以及對觀察者的增加或刪除的方法。而在具體主題(圖中的ConcreteSubject)中,包含了狀態屬性,以及狀態變化的方法,在自身發生變化時,會調用notifyObserver方法進行通知。
在觀察者的實現中,也存在抽象觀察者(Observer)和具體觀察者(ConcreteObserver)兩種角色。前者一般定義一個接口,用于在接收到變化通知時,對自身進行更新。而后者會實現具體的update方法,類似C#中我們訂閱事件之后觸發的回調方法。
以上就是我們在兩種語言中分別實現觀察者模式的方式,正如軟件工程強調的“沒有銀彈”的說法,觀察者模式雖然解決了很多問題,但也存在部分缺點,主要內容如下:
1、觀察者數量很多時,逐個通知會非常耗時。正如我們上述實現,存在一個ArrayList來保存所有的觀察者,如果這個ArrayList中的元素足夠大,那么在通知時程序的執行效率勢必是很低下的。
2、如果觀察目標與觀察者之間存在循環依賴時,觀察者模式會觸發雙方的循環調用,導致系統崩潰。
3、缺乏相應的機制通知觀察者觀察目標是如何發生變化的,觀察者僅僅是得知觀察目標發生了變化。當然這一點也不是絕對的,我們在程序實現時可以通過傳遞參數或者對象的方式去“告知”觀察者,觀察目標發生了哪些變化。
我們在講述觀察者模式時,反復提到了“主題”和“訂閱”的概念。從概念上理解而言,似乎觀察者模式,就是發布-訂閱模式,那么兩者之間究竟有沒有區別呢?我們一起進入下一章節來繼續探究。
發布訂閱模式
事實上,發布訂閱模式,和觀察者模式是有區別的。回到我們最開始的例子,微信公眾號的訂閱,看似是直接關注了公眾號,實質上,在關注和推送的兩種行為中,都是要通過“微信公眾平臺”這個第三方來實現的。看到這里,聰明的各位應該可以理解到發布訂閱模式的不同之處,沒錯,發布訂閱模式是在觀察者模式的基礎上,加入了“事件中心”的概念:
通過事件中心,發布者和訂閱者進行了進一步的解耦,發布者無需關心訂閱者的訂閱情況,而是直接發布主題到事件中心即可。而訂閱者也無需關心發布者自身的情況,甚至不知道發布者是何人,只需要接收事件中心的通知即可。
發布訂閱模式在目前的各種消息中間件中應用非常廣泛,如常見的RabbitMQ,kafka等,發布者發布主題,消費者訂閱對應的主題對發布的消息進行消費,相信大家對這些概念并不陌生。
小結
至此,我們今天要探究的主題就暫時告一段落。觀察者模式與發布訂閱模式如此相似,但又有所不同,在我們理清各自的概念和實現方式后,又會發現在我們日常的應用中這兩種模式無所不在。
設計模式本身就是一些優秀的前輩在開發過程中對一些最佳實踐和方法論做出的沉淀和總結,所以大家在提到這些內容時,不要先入為主的認為這些東西只是停留在概念階段,無法落地實踐。而是需要結合自己的實際工作,仔細思考設計模式該如何應用,如何選擇合適的設計模式,解決自己遇到的問題。當然,永遠沒有最優的方案,濫用設計模式只會大大降低程序的可讀性,對后續維護造成困難。活學活用,在這里祝愿大家可以和我一起學習,共同進步和成長,我們下期再見!
總結
以上是生活随笔為你收集整理的观察者模式VS发布-订阅模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: .NET再出发!20岁生日快乐
- 下一篇: WPF 实现调用本机摄像头~