在 Android 中實現 Redux 的一點經驗
簡評:Redux 是一個用於應用程式狀態管理的開源JavaScript庫,其核心是通過可管理和控制的狀態來描述一個系統。這意味著其思想其實是可以應用於任何型別應用的開發的,包括移動應用。
Redux 架構基於一個嚴格的單向資料流,應用中的所有資料都是通過元件在一個方向上流動。Redux 希望確保應用的檢視是根據確定的狀態來呈現的。意思就是,在任何時間點,你應用的狀態總是確定、有效的,並且可以轉換到另一個可預測和有效的狀態。而 UI 將根據所處的狀態來進行呈現。
關於 Redux 在網上已經有很多相關的資料,這裡就只介紹下 Redux 核心的三個元件:
1.Store:儲存應用的狀態並提供一些幫助方法來存取狀態,分發狀態以及註冊監聽。
2.Actions:簡單說 Actions 就是事件,包含要傳遞給 store 的資訊,表明我們希望怎樣改變應用的狀態。比如,定義如下的一個 action:
data class AddTodoAction(val text: String)
由 store 來進行分發:
store.dispatch(AddTodoAction("Write blog post"))
3.Reducers:進行狀態的轉變。類似這樣:
fun reduce(oldState: AppState, action: Action) : AppState {
return when (action) {
is AddToDoAction -> {
oldState.copy(todo = ...)
}
else -> oldState
}
}
介紹完核心元件,下面來看一下它們是怎麼組合到一起的:
Redux 的流程很簡單,你的應用根據當前狀態呈現 UI,使用者的互動觸發 action,並交給 reducer 來更新狀態。
最近,作者在一個還挺大的專案上試了下 Redux 架構,所以這裡就分享下從中總結的一些經驗。
1. 應用裡最好不要有多個 store
針對不同模組有不同的 store 似乎是個不錯的主意,但從上面的圖可以看到每個 store 和其資料流是一個閉環系統,這就使得不同 store 之間的狀態難以同步。這樣你就通常需要在一個狀態的變更響應中去進行另一個 store 的 action 分發,而這很容易造成無限迴圈。
另一個原因是多 store 的架構是非常僵化的,難以靈活的改動。
更好的做法是維護一個包含多個子狀態的全域性應用狀態,由一個 store 來表示:
data class AppState(val LoginState,
val HomeScreenState,
val GridState )
2. 保持應用的狀態層級儘可能少
因為 Redux 中 state 是不可變的,因此深層次巢狀的 state 會產生很多的樣板程式碼,並且難以更新。比如,考慮下面的一組資料模型:
data class State(val sections: List<Section>)
open class Section(val articles: List<Article>)
class Home(articles: List<Article>) : Section(articles)
class Discover(articles: List<Article>) : Section(articles)
class Article
例項化和更新狀態物件:
val state = State(sections = listOf(
Home(listOf(article1, article2)),
Discover(listOf(article1, article2))))
即使是用了 Kotlin 的 copy 機制,更新深層巢狀的屬性(比如上面的 Article)也是非常單調乏味的:
val newHome = Home(listOf(newArticle, state.sections[0].articles[1]))
state.copy(sections = listOf(newHome, state.sections[1]))
3. Reducers 只是純函式
Reduce 的作用只是處理 action 並返回新的 state 到 store 的,需要保證相同的輸入總會得到一樣的輸出。Reduce 自身不應該有狀態和執行任何額外工作,而只是做狀態轉換。
class Reducer {
fun reduce(state: State, action: Action) : State {
...
}
}
如果你需要響應某個 action,並執行一些操作,那應該考慮使用 Middleware。
4. 只用 Kotlin
Redux 很大部分受到 Flux 的啟發,而關於 Flux 最常見的抱怨就是需要寫一大堆的樣板程式碼。而所選擇的語言很大程度會決定你管理樣板程式碼的便利性。
Kotlin 中類似 data class,when 語句之類的特性,能讓你的程式碼清晰很多。例如,在 Reducer 中匹配 action 時,可以選擇用 instanceof 方法實現。
if (action instanceof AddTodoAction) {
return reduceAddTodoAction(oldState, action);
} else if (action instanceof RemoveTodoAction) {
return reduceRemoveTodoAction(oldState, action);
} else if (...) {
...
}
return oldState;
當 action 很多時,這種寫法就很痛苦了。如果用 Kotlin 就是這樣的:
return when (action) {
is AddTodoAction -> reduceAddTodoAction(oldState, action)
is RemoveTodoAction -> reduceRemoveTodoAction(oldState, action)
else -> oldState
}
結論
雖然,Redux 主要是被用於 Web 應用開發,但其思想我們還是可以學習並引入到 Android 中。但 Redux 也不是「銀彈」,事實上也沒有什麼架構是,其在 Android 上的應用還很新,但我們還是很希望能看到它的逐漸成熟。
如果你對 Redux 在 Android 上運用有興趣,可以看看 Redux 和 ReKotlin 這兩個庫。
英文原文:Lessons learned implementing Redux on Android - Pusher Blog
相關文章
- 經驗點談在JSP中的宣告. (轉)JS
- 使用PACKAGE的一點經驗Package
- 編譯核心的一點點經驗(轉)編譯
- 作培訓的一點經驗
- 實現一個Redux(完善版)Redux
- 一文了解深度學習在NLP中的最佳實踐經驗和技巧深度學習
- Fish Redux中的Dispatch是怎麼實現的?Redux
- 關於Presentation Error的一點經驗Error
- 英文投稿的一點經驗【轉載】
- 我的一點學習經驗 (轉)
- Flutter實現Android、iOS跨平臺經驗總結FlutterAndroidiOS
- Android幾個實戰經驗Android
- 如何實現一個 redux-observableRedux
- Spring Cloud在雲端計算SaaS中的實戰經驗分享SpringCloud
- 在程式碼中實現android:tint效果Android
- 手遊中實時音視訊的開發經驗與實現技巧
- 高可用性系統在大眾點評的實踐與經驗
- Linux配置mlterm的一點經驗(轉)Linux
- Redux在React中的使用小結ReduxReact
- 說說在 Android 的 RecyclerView 中如何實現下拉刷AndroidView
- 從0實現一個tiny-reduxRedux
- 深入理解redux原理,從零開始實現一個簡單的redux(包括react-redux, redux-thunk)ReduxReact
- 實驗| Pyecharts實現散點圖Echarts
- 從MySQL遷移到VoltDB的一點經驗MySql
- 初學J2ME的一點經驗
- root檔案系統的一點經驗(轉)
- flutter_redux 的實現原理FlutterRedux
- 【經驗分享】Python實現UI自動化難點問題PythonUI
- Windows安裝tensorflow的一點人生的經驗Windows
- 在知乎做營銷這兩年的一些真實經驗
- TRW2k一點點小小的經驗。 (290字)
- Immutable.js 以及在 react+redux 專案中的實踐JSReactRedux
- 我的 Android 開發實戰經驗總結Android
- 從平臺到中臺 | Elasticsearch 在螞蟻金服的實踐經驗Elasticsearch
- [譯] Story 中 Type Mode 在 iOS 和 Android 上的實現iOSAndroid
- 在android的spinner中,實現取VALUE值和TEXT值。Android
- Android中實現簡訊驗證碼自動填入Android
- Redux-實現createStoreRedux