在閒魚深度使用 Flutter 開發過程當中,咱們遇到了業務代碼耦合嚴重,代碼可維護性糟糕,如入泥濘。對於閒魚這樣的負責業務場景,咱們須要一個統一的應用框架來擺脫當下的開發困境,而這也是 Flutter 領域空缺的一塊處女地。
Fish Redux 是爲解決上面問題上層應用框架,它是一個基於 Redux 數據管理的組裝式 flutter 應用框架, 特別適用於構建中大型的複雜應用。
它的最大特色是配置式組裝, 一方面將一個大的頁面,對視圖和數據層層拆解爲互相獨立的 Component|Adapter,上層負責組裝,下層負責實現,另外一方面將 Component|Adapter 拆分爲 View,Reducer,Effect 等相互獨立的上下文無關函數。因此它會很是乾淨,易編寫、易維護、易協做。
Fish Redux 的靈感主要來自於 Redux、React、Elm、Dva 這樣的優秀框架,而 Fish Redux 站在巨人的肩膀上,將集中,分治,複用,隔離作的更進一步。前端
架構圖,主體自底而上,分三層,每一層用來解決不通層面的問題和矛盾,下面依次來展開。android
Redux 作什麼的?git
Redux 是怎麼設計和實現的?程序員
Redux 是一個函數式的數據管理的框架。github
傳統 OOP 作數據管理,每每是定義一些 Bean,每個 Bean 對外暴露一些 Public-API 用來操做內部數據(充血模型)。 函數式的作法是更上一個抽象的緯度,對數據的定義是一些 Struct(貧血模型),而操做數據的方法都統一到具備相同函數簽名 (T, Action) => T 的 Reducer 中。 FP:Struct(貧血模型) + Reducer = OOP:Bean(充血模型) 同時 Redux 加上了 FP 中經常使用的 Middleware(AOP) 模式和 Subscribe 機制,給框架帶了極高的靈活性和擴展性。 貧血模型、充血模型 參考: [https://en.wikipedia.org/wiki/Plain_old_Java_object](https://en.wikipedia.org/wiki/Plain_old_Java_object)
Redux 的缺點redux
在咱們實際使用 Redux 中面臨兩個具體問題性能優化
Fish Redux 的改良架構
Fish Redux 經過 Redux 作集中化的可觀察的數據管理。然不只於此,對於傳統 Redux 在使用層面上的缺點,在面向端側 flutter 頁面緯度開發的場景中,咱們經過更好更高的抽象,作了改良。
一個組件須要定義一個數據(Struct)和一個 Reducer。同時組件之間存在着父依賴子的關係。經過這層依賴關係,
咱們解決了【集中】和【分治】之間的矛盾,同時對 Reducer 的手動層層 Combine 變成由框架自動完成,大大簡化了使用 Redux 的困難。
咱們獲得了理想的集中的效果和分治的代碼。app
對社區標準的 follow框架
組件是對局部的展現和功能的封裝。 基於 Redux 的原則,咱們對功能細分爲修改數據的功能(Reducer)和非修改數據的功能(反作用 Effect)。
因而咱們獲得了,View、 Effect、Reducer 三部分,稱之爲組件的三要素,分別負責了組件的展現、非修改數據的行爲、修改數據的行爲。
這是一種面向當下,也面向將來的拆分。在面向當下的 Redux 看來,是數據管理和其餘。在面向將來的 UI-Automation 看來是 UI 表達和其餘。
UI 的表達對程序員而言即將進入黑盒時代,研發工程師們會把更多的精力放在非修改數據的行爲、修改數據的行爲上。
組件是對視圖的分治,也是對數據的分治。經過逐層分治,咱們將複雜的頁面和數據切分爲相互獨立的小模塊。這將利於團隊內的協做開發。
關於 View
View 僅僅是一個函數簽名: (T,Dispatch,ViewService) => Widget
它主要包含三方面的信息
須要用到的組件依賴等,經過 ViewService 標準化調用。
好比一個典型的符合 View 簽名的函數![image.png](https://img.alicdn.com/tfs/TB1ymUNCgHqK1RjSZFPXXcwapXa-1198-1098.png)
關於 Effect
Effect 是對非修改數據行爲的標準定義,它是一個函數簽名: (Context, Action) => Object
它主要包含四方面的信息
它的返回值僅限於 bool or Future, 對應支持同步函數和協程的處理流程。
好比:良好的協程的支持![image.png](https://img.alicdn.com/tfs/TB1bTgVChYaK1RjSZFnXXa80pXa-1256-944.png)
關於 Reducer
Reducer 是一個徹底符合 Redux 規範的函數簽名:(T,Action) => T
一些符合簽名的 Reducer
同時咱們以顯式配置的方式來完成大組件所依賴的小組件、適配器的註冊,這份依賴配置稱之爲 Dependencies。
因此有這樣的公式 Component = View + Effect(可選) + Reducer(可選) + Dependencies(可選)。
一個典型的組裝
經過 Component 的抽象,咱們獲得了完整的分治,多緯度的複用,更好的解耦。
Adapter 也是對局部的展現和功能的封裝。它爲 ListView 高性能場景而生,它是 Component 實現上的一種變化。
它的目標是解決 Component 模型在 flutter-ListView 的場景下的 3 個問題
3)Effect 的生命週期和 View 的耦合,在 ListView 的場景下不符合直觀的預期。
歸納的講,咱們想要一個邏輯上的 ScrollView,性能上的 ListView ,這樣的一種局部展現和功能封裝的抽象。 作出這樣獨立一層的抽象是, 咱們看實際的效果, 咱們對頁面不使用框架,使用框架 Component,使用框架 Component+Adapter 的性能基線對比
推薦的目錄結構會是這樣
sample_page -- action.dart -- page.dart -- view.dart -- effect.dart -- reducer.dart -- state.dart components sample_component -- action.dart -- component.dart -- view.dart -- effect.dart -- reducer.dart -- state.dart
上層負責組裝,下層負責實現, 同時會有一個插件提供, 便於咱們快速填寫。
以閒魚的詳情場景爲例的組裝:
組件和組件之間,組件和容器之間都徹底的獨立。
組件|適配器間內通訊
![image.png](https://img.alicdn.com/tfs/TB1GrISCkzoK1RjSZFlXXai4VXa-1846-986.png) 簡單的描述:採用的是帶有一段優先處理的廣播, self-first-broadcast。 發出的 Action,本身優先處理,不然廣播給其餘組件和 Redux 處理。 最終咱們經過一個簡單而直觀的 dispatch 完成了組件內,組件間(父到子,子到父,兄弟間等)的全部的通訊訴求。
數據刷新
層層的數據的拷貝
另外一方面也是對數據驅動展現的嚴格的 follow。
![image.png](https://img.alicdn.com/tfs/TB1BjQLCkvoK1RjSZFNXXcxMVXa-1714-828.png)
視圖刷新
扁平化通知到全部組件,組件經過 shouldUpdate 肯定本身是否須要刷新
![image.png](https://img.alicdn.com/tfs/TB1PkgHCbPpK1RjSZFFXXa5PpXa-1380-620.png)
數據的集中管理
組件的分治管理
View、Reducer、Effect 隔離
聲明式配置組裝
良好的擴展性
核心框架保持本身的核心的三層關注點,不作核心關注點之外的事情,同時對上層保持了靈活的擴展性。
精小、簡單、完備
Fish Redux 目前已在阿里巴巴閒魚技術團隊內多場景,深刻應用。
本文爲雲棲社區原創內容,未經容許不得轉載。