flutter全局數據共享通知方案

讓咱們先拋開Flutter這個平臺說話,若是讓你實現數據共享,你能想到的基礎方案有哪些。
  • 全局靜態變量
  • 單例(XXXMnager,如UserManger)
  • 持久化(SharePref)
ok,以上方案真的是簡單粗暴,好用到哭,然而,設計到數據數據變動以後及時通知到各個關注方就顯得有點捉襟見肘了。
所以,由於有這樣的一些需求存在,業界的一些大神(懶人)們經過不懈的努力,作出了一些驚天地,泣鬼神的全局數據共享通知方案。
那麼,在flutter上,我比較關注的是, Redux,和 event_bus 了,本文就是想來總結一下本身對Redux和event_bus的理解心得。

Redux

理解成本比較高,我的以爲耦合性也比較高,要搞清楚redux的原理,先要了解一下幾個概念

Store

這裏是他的構造函數,咱們先不要管裏面的一堆參數,看一眼就好。
Store(
    this.reducer, {
    State initialState,
    List<Middleware<State>> middleware = const [],
    bool syncStream: false,

    /// If set to true, the Store will not emit onChange events if the new State
    /// that is returned from your [reducer] in response to an Action is equal
    /// to the previous state.
    ///
    /// Under the hood, it will use the `==` method from your State class to
    /// determine whether or not the two States are equal.
    bool distinct: false,
  })複製代碼
Store能夠簡單的理解爲一個容納各類數據以及對數據處理的action的一個倉庫,能夠看到能夠給它配置一個泛型,這個泛型表明的就是下面的State,好,咱們接着看State。

State

State實際上並非Dart的基礎類型,他其實就是上面Store定義中的那個S,對的,他就是一個泛型,他能夠是dart基礎類型String,int,double,也能夠是你定義的class,都ok。總之一句話,他就是Store要守護的和維護的那個份數據。

StoreProvider

這裏是他的構造函數,這裏的參數比較簡單,能夠直接就瞭解一下
const StoreProvider({
    Key key,
    @required Store<S> store,
    @required Widget child,
  })複製代碼
一個store,一個child是一個Widget類型,因此理解起來是否是就是將這個store和child綁定起來的橋樑啊,嗯,牽線媒婆,store中的數據有變動能夠通知到到child更新tree,那麼具體child中的哪些個子child須要更新,是有誰決定的,固然是StoreConnector,媒婆把人給你放一塊兒,你牽不牽手他可無論,誰管,確定是StoreConnector啊,好,咱們看StoreConnector。

StoreConnector

仍是來看一下構造函數
StoreConnector({
    Key key,
    @required this.builder,
    @required this.converter,
    this.distinct = false,
    this.onInit,
    this.onDispose,
    this.rebuildOnChange = true,
    this.ignoreChange,
    this.onWillChange,
    this.onDidChange,
    this.onInitialBuild,
  })複製代碼
這個構造函數的參數就有點多了,若是你感興趣能夠都瞭解一下,沒時間的話,只須要了解required標記的。第一個是builder,這個就是WidgetBuilder,很明顯,構建view用的,很是重點的converter這個參數,看一下converter的定義:
/// Convert the entire Store into a ViewModel. The ViewModel will be used

/// to build a Widget using the ViewModelBuilder.

typedef StoreConverter<S, ViewModel> = ViewModel Function(

  Store<S> store,

);複製代碼
看到以後也就沒那麼神祕了,就是將store轉換爲了ViewModel,轉了以後,實際上就是能夠更好的將數據交給builder去構建view,是嗎?難道不是嗎?咱們前面提到了store能夠接受到一個改變裏面數據的action,那麼這些action是誰給處理的呢?回過頭來看Store的構造函數,裏面的第一個參數是reducer,reducer的英文翻譯爲減速器,還原劑,反正就是聽着挺彆扭的,他不就是一個狀態轉換器嘛,數據有一個狀態,通過action的處理,變成另一個狀態,是嗎,這樣你好理解了麼?好吧,來看看Reducer。

Reducer

Reducer的定義以下:
typedef State Reducer<State>(State state, dynamic action);複製代碼
一目瞭然,就是上面所說的狀態應該action處理,變爲另一個狀態,那麼,state的處理僅僅只有Reducer處理,加入須要加入一些日誌記錄的,性能監控等處理,該怎麼辦呢?這種需求處處都有啊,大名鼎鼎的okhttp,處理一個http請求也能夠說成是一個一系列的請求參數json請過action後端服務器的處理變爲另一串json,對麼,那麼對請求頭,請求參數校驗的一些處理,是否是都交給了攔截器interceptor?這點設計思路是想通的,所以這裏的Middleware中間件雖然叫起來很神祕,可是他實際上就是攔截器,他在Reducer們以前執行,這點我瞭解到的是如此,有不一樣的看法的同窗能夠在評論中留下建議。

Middleware

定義以下
/// ### Example
///
///     loggingMiddleware(Store<int> store, action, NextDispatcher next) {
///       print('${new DateTime.now()}: $action');
///
///       next(action);
///     }
///
///     // Create your store with the loggingMiddleware
///     final store = new Store<int>(
///       counterReducer,
///       middleware: [loggingMiddleware],
///     );
typedef void Middleware<State>(
  Store<State> store,
  dynamic action,
  NextDispatcher next,
);複製代碼
對,處理完以後,交給後面的action,理解起來也沒什麼成本了,好,那麼總結一下咱們將的這些概念,將他們串起來,用一副圖來表達。


用一句話來描述就是:
store經過storeProvider將本身給暴露出來,交給StoreConnector來更好連接到控件上,控件(也不必定須要在控件哪裏,只不過咱們好理解點)發送action交給store中的reducer處理,若是有中間件存在,那麼中間件先攔截以後在交給recuder處理。處理以後store中的數據變動了,將會經有storeConnector通知組件更新。ok流程就這麼跑完了。

event_bus

理解成本略低,耦合性也較低
初始化
import 'package:event_bus/event_bus.dart';

EventBus eventBus = new EventBus();複製代碼
發送事件
eventBus.fire(event);複製代碼
監聽事件
eventBus.on().listen((event) { 
    print(event.runtimeType);
});複製代碼
也沒有太多的概念,無恥的盜一幅圖來講就是


用一句話總結就是:對於某處所作的變動,若是想通知出去,那麼交給總線吧,誰想關心誰問總線取。

總結

整體上來看,redux和bus均可以實現全局數據共享及變動通知,可是bus更加好理解概念也每有那麼多,也不像redux須要經過storeConnector那麼與控件綁定,形成沒必要要的耦合,我的傾向於使用bus解決全局數據共享變動通知的需求。


Flutter Event Bus 實現原理傳送門

相關文章
相關標籤/搜索