EventBus的缺點及改進公升級

2021-08-26 03:09:21 字數 2867 閱讀 5052

eventbus很屌,被廣泛用於事件分發、工程解耦,現在已經出到了第3版eventbuds3。網上對它的介紹太多了,我這裡就不詳細展開了。有不熟悉的可以閱讀以下這篇文章:

《老司機教你「飆」eventbus3》

然而本文並不是靠吹噓eventbus來裝逼的,相反,我要數落一下它的缺點,並推介一下eventbus4(本人命名的,未得到官方背書)。

缺點如下:

事件只能通過事件的類名來區分;

這恐怕是eventbus最坑爹的設計了,eventbus吹捧者們難道沒注意到它這一點嗎?這至少帶來了3大問題:

操作麻煩,每乙個事件,都要定義乙個類;

增加方法數;

導致事件傳送者和接收者都依賴耦合事件類;

事件發生者只能單向廣播,無法獲得接收者對事件的處理結果;

eventbus能確保事件被送達給感興趣的監聽者。但這一過程是單向的。就像直流電一樣,電流永遠是從正極流向負極,無法「交流」(在現代社會中,交流電遠比直流電用途廣嘛)。誰規定的event應該單向傳遞呢。很多時候,event傳送者把event傳送出去了,是很希望得到反饋的:小王,事情處理得怎麼樣了,有什麼結論?結果小王一言不發,低頭做事。沒有交流的協作是低效的寫作。

所有事件監聽者(subscriber)都必須顯性註冊;

或許eventbus的開發者覺得每乙個事件接收者,向eventbus的**序號產生器構註冊一下自己,並不是一件費力的事情,也就一行**而已(註冊與反註冊,其實有2行**)。但對很多挑剔的程式設計師來說,這是件很不爽的事情。 我已經在註解裡宣告了自己,憑什麼還要冗餘地再註冊一次,你很不得了麼?明明大量的場景下,事件監聽者是在程式一啟動就需要監聽事件的(不要提sticky,sticky是很weird的邏輯)。

eventbus4很完美地解決了這些問題。它在這幾個方面對eventbus做了重要擴充套件:

事件過濾器(filter);

先看看示例**:

@subscribe

(filter ="event1")

publicvoidon

event1emitted

(object obj)

filter其實是個很好理解的概念。事件有很多,監聽者需要「篩選」、「過濾」一下,只監聽我關心的事件。它是定義在subscribe註解裡面的。有了filter,就再也不需要為監聽者定義事件class了。省時省力;事件傳送者與監聽者的依賴被大大降低(嚴格說來還對字串」event1」有依賴);而且,這樣的**不是更簡潔、優雅麼?

讓事件傳送者和監聽者可以「交流」(process);

還是先看示例**:

object obj = eventbus.

getdefault

().process(new

status.status_playing);

在大量的場景中,我丟擲乙個事件(或者叫做訊息message),其實希望得到別人對該事件的回應。也就是我通過丟擲事件來完成一次我對別人的呼叫。這樣的需求,eventbus完全應該滿足啊,而且鑑於它的架構特點,也是責無旁貸的。

我實現了這個process()方法,專門解決這個需求。當然,該事件的監聽者應當有且僅有乙個。如果定義多了,eventbus也只會把事件傳給第乙個監聽者,其他的被忽略掉了。至於那些想要一次呼叫就得到多個被呼叫者的返回結果的需求,我覺得多半是偽需求,暫不考慮。

獨占性接收者(exclusive subscriber);

正是因為有大量的場景,是事件傳送者希望獲得事件接收者的處理結果的,所以才誕生了」獨占性接收者」。

獨吞事件:宣告自己是該事件唯一的接收者,不允許別的接收者染指;

排他性檢查:若有兩個及以上定義exclusive的接收者,則編譯告警;

讀者可能已經猜到了,這其實就是一種「介面暴露」,用於乙個元件/模組對外提供能力服務。呼叫者可以簡單地通過乙個事件呼叫它。

示例**:

@subscribe

(filter ="getuserinfo"

, exclusive =true

)public int

getuserinfo

(object obj)

全域性事件監聽者;

乙個監聽者若比較貪婪,想監聽程式從啟動到退出期間一切事件,怎麼辦?原始落後的eventbus3居然想到的是用sticky(粘性事件,前文說了,這很weird)來解決,太笨重了。需要單獨拋sticky事件不說,還需要快取住所有sticky事件。如果某個事件發生的特別頻繁,一分鐘產生成千上萬個,那豈不是要快取成千上萬個事件?那會導致多少潛在記憶體洩漏,又有多少sticky事件的監聽者在註冊的那一刻因大量事件處理而卡死?

這個時候需要的是全域性的事件監聽者。

示例如下:

@subscribe

(filter ="event1"

)publicstaticint

onevent1emitted

(object obj)

它的特點如下:

必須是靜態公共方法(才能被「全域性」使用);

無需開發者顯性註冊(編譯期自動註冊);

可取消註冊(結束「全域性監聽」的能力);

既然繼承於eventbus,eventbus4也就是乙個開源專案,利用業餘時間完成,遵循apache-2.0開源協議。

HDFS的缺點及改進策略

hdfs是乙個不錯的分布式檔案系統,它有很多的優點,但也存在有一些缺點。目前而言,它在以下幾個方面就效率不佳 低延時訪問 hdfs不太適合於那些要求低延時 數十毫秒 訪問的應用程式,因為hdfs是設計用於大吞吐量資料的,這是以一定延時為代價的。hdfs是單master的,所有的對檔案的請求都要經過它...

HDFS的缺點及改進策略

hdfs是乙個不錯的分布式檔案系統,它有很多的優點,但也存在有一些缺點。目前而言,它在以下幾個方面就效率不佳 低延時訪問 hdfs不太適合於那些要求低延時 數十毫秒 訪問的應用程式,因為hdfs是設計用於大吞吐量資料的,這是以一定延時為代價的。hdfs是單master的,所有的對檔案的請求都要經過它...

HDFS缺點及改進策略

hdfs是乙個不錯的分布式檔案系統,它有很多的優點,但也存在有一些缺點。目前而言,它在以下幾個方面就效率不佳 低延時訪問 hdfs不太適合於那些要求低延時 數十毫秒 訪問的應用程式,因為hdfs是設計用於大吞吐量資料的,這是以一定延時為代價的。hdfs是單master的,所有的對檔案的請求都要經過它...