日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

MVI 架构

發布時間:2024/1/23 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MVI 架构 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

近日,600多名谷歌員工簽署了一份宣言,反對該公司強制接種新冠疫苗。這對谷歌領導層構成了最新挑戰,因為該公司即將迎來讓員工重返辦公室的關鍵最后期限。拜登政府已下令,員工人數在百人以上的美國公司,需要在2022年1月4日前確保員工全面接種疫苗或定期檢測新冠肺炎。泄露的谷歌內部文件顯示,該公司要求其超過15萬名員工在12月3日之前將疫苗接種狀態上傳到其內部系統上,無論他們是否計劃復崗。谷歌還表示,所有直接或間接履行政府合同的員工都必須接種疫苗,即使他們在家工作也是如此。

/ 作者簡介 /

本篇文章來自RicardoMJiang的投稿,文章主要分享了作者對目前架構進行總結并延伸的相關內容,相信會對大家有所幫助!同時也感謝作者貢獻的精彩文章。
/ 前言 /

Android開發發展到今天已經相當成熟了,各種架構大家也都耳熟能詳,如MVC,MVP,MVVM等,其中MVVM更是被官方推薦,成為Android開發中的顯學。

不過軟件開發中沒有銀彈,MVVM架構也不是盡善盡美的,在使用過程中也會有一些不太方便之處,而MVI可以很好的解決一部分MVVM的痛點。

本文主要包括以下內容

MVC,MVP,MVVM等經典架構介紹
MVI架構到底是什么?
MVI架構實戰

需要重點指出的是,標題中說MVI架構是MVVM的進階版是指MVI在MVVM非常相似,并在其基礎上做了一定的改良,并不是說MVI架構一定比MVVM適合你的項目。各位同學可以在分析比較各個架構后,選擇合適項目場景的架構

/ 經典架構介紹 /

MVC架構介紹

MVC是個古老的Android開發架構,隨著MVP與MVVM的流行已經逐漸退出歷史舞臺,我們在這里做一個簡單的介紹,其架構圖如下所示:

圖片

MVC架構主要分為以下幾部分:

視圖層(View):對應于xml布局文件和java代碼動態view部分
控制層(Controller):主要負責業務邏輯,在android中由Activity承擔,同時因為XML視圖功能太弱,所以Activity既要負責視圖的顯示又要加入控制邏輯,承擔的功能過多。
模型層(Model):主要負責網絡請求,數據庫處理,I/O的操作,即頁面的數據來源

由于android中xml布局的功能性太弱,Activity實際上負責了View層與Controller層兩者的工作,所以在android中mvc更像是這種形式:

圖片

因此MVC架構在android平臺上的主要存在以下問題:

Activity同時負責View與Controller層的工作,違背了單一職責原則
Model層與View層存在耦合,存在互相依賴,違背了最小知識原則

MVP架構介紹

由于MVC架構在Android平臺上的一些缺陷,MVP也就應運而生了,其架構圖如下所示:

圖片

MVP架構主要分為以下幾個部分:

View層:對應于Activity與XML,只負責顯示UI,只與Presenter層交互,與Model層沒有耦合
Presenter層:主要負責處理業務邏輯,通過接口回調View層
Model層:主要負責網絡請求,數據庫處理等操作,這個沒有什么變化

我們可以看到,MVP解決了MVC的兩個問題,即Activity承擔了兩層職責與View層與Model層耦合的問題。但MVP架構同樣有自己的問題:

Presenter層通過接口與View通信,實際上持有了View的引用
但是隨著業務邏輯的增加,一個頁面可能會非常復雜,這樣就會造成View的接口會很龐大。

MVVM架構介紹

MVVM 模式將 Presenter 改名為 ViewModel,基本上與 MVP 模式完全一致。唯一的區別是,它采用雙向數據綁定(data-binding):View的變動,自動反映在 ViewModel,反之亦然。

MVVM架構圖如下所示:

圖片

可以看出MVVM與MVP的主要區別在于,你不用去主動去刷新UI了,只要Model數據變了,會自動反映到UI上。換句話說,MVVM更像是自動化的MVP。

MVVM的雙向數據綁定主要通過DataBinding實現,不過相信有很多人跟我一樣,是不喜歡用DataBinding的,這樣架構就變成了下面這樣。

圖片

View觀察ViewModel的數據變化并自我更新,這其實是單一數據源而不是雙向數據綁定,所以其實MVVM的這一大特性我其實并沒有用到
View通過調用ViewModel提供的方法來與ViewModel交互

小結

MVC架構的主要問題在于Activity承擔了View與Controller兩層的職責,同時View層與Model層存在耦合
MVP引入Presenter層解決了MVC架構的兩個問題,View只能與Presenter層交互,業務邏輯放在Presenter層
MVP的問題在于隨著業務邏輯的增加,View的接口會很龐大,MVVM架構通過雙向數據綁定可以解決這個問題
MVVM與MVP的主要區別在于,你不用去主動去刷新UI了,只要Model數據變了,會自動反映到UI上。換句話說,MVVM更像是自動化的MVP。
MVVM的雙向數據綁定主要通過DataBinding實現,但有很多人(比如我)不喜歡用DataBinding,而是View通過LiveData等觀察ViewModle的數據變化并自我更新,這其實是單一數據源而不是雙向數據綁定

/ MVI架構到底是什么 /

MVVM架構有什么不足?

要了解MVI架構,我們首先來了解下MVVM架構有什么不足,相信使用MVVM架構的同學都有如下經驗,為了保證數據流的單向流動,LiveData向外暴露時需要轉化成immutable的,這需要添加不少模板代碼并且容易遺忘,如下所示:

class TestViewModel : ViewModel() {
//為保證對外暴露的LiveData不可變,增加一個狀態就要添加兩個LiveData變量
private val _pageState: MutableLiveData = MutableLiveData()
val pageState: LiveData = _pageState
private val _state1: MutableLiveData = MutableLiveData()
val state1: LiveData = _state1
private val _state2: MutableLiveData = MutableLiveData()
val state2: LiveData = _state2
//…
}

如上所示,如果頁面邏輯比較復雜,ViewModel中將會有許多全局變量的LiveData,并且每個LiveData都必須定義兩遍,一個可變的,一個不可變的。這其實就是我通過MVVM架構寫比較復雜頁面時最難受的點。其次就是View層通過調用ViewModel層的方法來交互的,View層與ViewModel的交互比較分散,不成體系。

小結一下,在我的使用中,MVVM架構主要有以下不足:

為保證對外暴露的LiveData是不可變的,需要添加不少模板代碼并且容易遺忘
View層與ViewModel層的交互比較分散零亂,不成體系

MVI架構是什么?

MVI與MVVM很相似,其借鑒了前端框架的思想,更加強調數據的單向流動和唯一數據源,架構圖如下所示:

圖片

其主要分為以下幾部分:

Model:與MVVM中的Model不同的是,MVI的Model主要指UI狀態(State)。例如頁面加載狀態、控件位置等都是一種UI狀態
View:與其他MVX中的View一致,可能是一個Activity或者任意UI承載單元。MVI中的View通過訂閱Intent的變化實現界面刷新(注意:這里不是Activity的Intent)
Intent:此Intent不是Activity的Intent,用戶的任何操作都被包裝成Intent后發送給Model層進行數據請求

單向數據流

MVI強調數據的單向流動,主要分為以下幾步:

用戶操作以Intent的形式通知Model
Model基于Intent更新State
View接收到State變化刷新UI

數據永遠在一個環形結構中單向流動,不能反向流動:

圖片

上面簡單的介紹了下MVI架構,下面我們一起來看下具體是怎么使用MVI架構的。

/ MVI架構實戰 /

總體架構圖

圖片

我們使用ViewModel來承載MVI的Model層,總體結構也與MVVM類似,主要區別在于Model與View層交互的部分:

Model層承載UI狀態,并暴露出ViewState供View訂閱,ViewState是個data class,包含所有頁面狀態
View層通過Action更新ViewState,替代MVVM通過調用ViewModel方法交互的方式

MVI實例介紹

添加ViewState與ViewEvent

ViewState承載頁面的所有狀態,ViewEvent則是一次性事件,如Toast等,如下所示:

data class MainViewState(val fetchStatus: FetchStatus, val newsList: List)

sealed class MainViewEvent {
data class ShowSnackbar(val message: String) : MainViewEvent()
data class ShowToast(val message: String) : MainViewEvent()
}

我們這里ViewState只定義了兩個,一個是請求狀態,一個是頁面數據
ViewEvent也很簡單,一個簡單的密封類,顯示Toast與Snackbar

ViewState更新

class MainViewModel : ViewModel() {
private val _viewStates: MutableLiveData = MutableLiveData()
val viewStates = _viewStates.asLiveData()
private val _viewEvents: SingleLiveEvent = SingleLiveEvent()
val viewEvents = _viewEvents.asLiveData()

init {emit(MainViewState(fetchStatus = FetchStatus.NotFetched, newsList = emptyList())) }private fun fabClicked() {count++emit(MainViewEvent.ShowToast(message = "Fab clicked count $count")) }private fun emit(state: MainViewState?) {_viewStates.value = state }private fun emit(event: MainViewEvent?) {_viewEvents.value = event }

}

如上所示:

我們只需定義ViewState與ViewEvent兩個State,后續增加狀態時在data class中添加即可,不需要再寫模板代碼
ViewEvents是一次性的,通過SingleLiveEvent實現,當然你也可以用Channel當來實現
當狀態更新時,通過emit來更新狀態

View監聽ViewState

private fun initViewModel() {viewModel.viewStates.observe(this) {renderViewState(it)}viewModel.viewEvents.observe(this) {renderViewEvent(it)} }

如上所示,MVI使用ViewState對State集中管理,只需要訂閱一個ViewState便可獲取頁面的所有狀態,相對MVVM減少了不少模板代碼。

View通過Action更新State

class MainActivity : AppCompatActivity() {
private fun initView() {
fabStar.setOnClickListener {
viewModel.dispatch(MainViewAction.FabClicked)
}
}
}
class MainViewModel : ViewModel() {
fun dispatch(action: MainViewAction) =
reduce(viewStates.value, action)

private fun reduce(state: MainViewState?, viewAction: MainViewAction) {when (viewAction) {is MainViewAction.NewsItemClicked -> newsItemClicked(viewAction.newsItem)MainViewAction.FabClicked -> fabClicked()MainViewAction.OnSwipeRefresh -> fetchNews(state)MainViewAction.FetchNews -> fetchNews(state)} }

}

如上所示,View通過Action與ViewModel交互,通過Action通信,有利于View與ViewModel之間的進一步解耦,同時所有調用以Action的形式匯總到一處,也有利于對行為的集中分析和監控。

/ 總結 /

本文主要介紹了MVC,MVP,MVVM與MVI架構,目前MVVM是官方推薦的架構,但仍然有以下幾個痛點:

MVVM與MVP的主要區別在于雙向數據綁定,但由于很多人(比如我)并不喜歡使用DataBindg,其實并沒有使用MVVM雙向綁定的特性,而是單一數據源
當頁面復雜時,需要定義很多State,并且需要定義可變與不可變兩種,狀態會以雙倍的速度膨脹,模板代碼較多且容易遺忘
View與ViewModel通過ViewModel暴露的方法交互,比較零亂難以維護

而MVI可以比較好的解決以上痛點,它主要有以下優勢:

強調數據單向流動,很容易對狀態變化進行跟蹤和回溯
使用ViewState對State集中管理,只需要訂閱一個ViewState便可獲取頁面的所有狀態,相對 MVVM 減少了不少模板代碼
ViewModel通過ViewState與Action通信,通過瀏覽ViewState和Aciton定義就可以理清ViewModel的職責,可以直接拿來作為接口文檔使用。

當然MVI也有一些缺點,比如:

所有的操作最終都會轉換成State,所以當復雜頁面的State容易膨脹
State是不變的,因此每當State需要更新時都要創建新對象替代老對象,這會帶來一定內存開銷

軟件開發中沒有銀彈,所有架構都不是完美的,有自己的適用場景,讀者可根據自己的需求選擇使用。

但通過以上的分析與介紹,我相信使用MVI架構代替沒有使用DataBinding的MVVM是一個比較好的選擇~

總結

以上是生活随笔為你收集整理的MVI 架构的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。