[Flutter] Cubit介紹&Bloc優缺比較

Tsai Rene
Nov 5, 2020

--

使用 Flutter 的開發者對 bloc 這 library 大概都不陌生,可能也很習慣於使用 事件觸發 event-driven 的形式來更新 UI 了。但在 bloc library v5.0.0 之後的發佈裡(changelog),可能會發現作者做了一系列的重構,新增了 Cubit 類別,並把 Bloc 從繼承 Stream 改為繼承 Cubit,目的就是為了提供一個更簡單的 bloc pattern 實作。對這些前因後果有興趣的,可以看這篇,想看中文的,中文翻譯獻上

簡而言之,作者發現有許多使用 bloc 的開發者有不同於他預期的用法,且許多開發者覺得直接呼叫函式(function)比觸發事件(event)來得容易。所以在基於原本 bloc 的架構下,導入了 cubit 來簡化狀態的改變。接下來會以實際範例來介紹 cubit 並比較與之前使用 bloc 的區別。

cubit 簡介

  • Cubit 是 Bloc 的基礎類別(Base Class)。
  • Cubit 可以定義被用來觸發事件的 function 讓外部使用。
    - 狀態(States)是Cubit的 output,代表你應用程式中的一部分狀態。
    - UI 元件可以被通知來更新狀態並重繪某些部分。
Cubit & Bloc class

使用須知:

  1. 建立一個 Cubit 時,需定義狀態類別,可以是原始型別 primitive type(簡單狀態)或是自訂類別(複雜情況)。
  2. 必須給定初始狀態。可透過呼叫 super 給定。
  3. 可以透過 emit 來改變狀態。(emit protected 所以只能在 Cubit 裡使用)
  4. 只有在呼叫listen之後的狀態改變會被觸發。
官方文件上的計數器範例 — 宣告
官方文件上的計數器範例 — 使用
官方文件上的計數器範例 — 監控狀態變化

cubit vs bloc

cubit
bloc
  • cubit 優點:
    簡單、簡潔且較少程式碼。cubit(state only), bloc(state, event and mapEventToState)。不需要使用 async* 也不需要了解 yield* 的概念,僅需呼叫 emit 來作狀態切換。
  • bloc 優點:
    1. 可追溯性高:bloc 最大的優點就是能知道一系列的事件觸發順序與狀態的改變。因此對於需要清楚知道狀態改變的功能來說會是一大優點。最常見的例子大概是認證/登錄。
    2. Bloc優於Cubit的另一個領域是我們需要利用響應式編程(reactive operators),像是buffer, debounceTime, throttle,等。舉例來說,如果我們需要實作一個即時的搜尋功能,但我們會想要減少跟server的request(debounce)以避免達到上限限制及減輕server負荷。在bloc中可以override transformEvents 來改變傳入event的處理。
認證範例 — bloc能了解狀態變換的緣由
即時搜尋範例 — debounce

總結

Cubit 大幅減低了使用 Bloc 的複雜度及減少 boilerplate code,卻還是能與 bloc 兼容操作。對於新的開發人員來說,上手難度更是降低不少。也因為能與 bloc 相容,如果一開始在選擇上不知道該以 cubit 還是 bloc 實作的話,建議先以 cubit 實作,必要時還是能快速重構成 bloc !

--

--