各种模式对比
从 mvc 到 mvp,mvvm 再到 mvi,目的是让代码结构更清晰,更容易维护。
模式 | 优点 | 缺点 |
---|---|---|
mvc | 简单,快速 ,适合小项目 | controller会越来越臃肿,view和model耦合 |
mvp | view只依赖于presenter层,解耦view和model | presenter通过接口回调给view,接口会越来越多,有内存泄漏风险 |
mvvm | viewModel和view数据双向绑定,不需要过多接口,隐藏回调细节,减少内存泄漏风险 | 实现起来复杂 |
mvi | 将数据封装成userIntent和uistate,实现数据单向流动,结构更加简单 | 实现起来复杂,userIntent和uistate容易膨胀 |
其中这篇文章有非常详细的介绍:
https://blog.csdn.net/lengjiye/article/details/129736951
mvi 的模板代码
userIntent
将 view 的一些操作封装各种 Intent
interface IUserIntent {
}
例如,以下是登录界面的各种意图
sealed class LoginUserIntent : IUserIntent {
data class PhoneNumLogin(val phone: String) : LoginUserIntent()
data class facebookLogin(val accountNum: String) : LoginUserIntent()
data class WechatLogin(val wechatAccount: String) : LoginUserIntent()
}
uistate
我们在进行一些逻辑运算之后,会获取到各种数据,然后将这些数据封装成 uistate
interface IUiState {
}
例如,登录界面的各种状态
sealed class LoginUiState : IUiState {
data class LoginSuccessState(val type: String, val userId: String?) : LoginUiState()
data class LoginFailedState(val type: String,val errCode: Int, val msg: String?) : LoginUiState()
}
模板
abstract class BaseViewModel<I: IUserIntent,S: IUiState> : ViewModel() {
private val _userIntentFlow: MutableStateFlow<I> = MutableStateFlow(mNoneValueIntent)
protected val mUiState: MutableLiveData<S> = MutableLiveData()
abstract val mNoneValueIntent: I
init {
/**
* 处理用户意图
*/
_userIntentFlow.onEach { userIntent ->
println("userIntentFlow onEach:$userIntent")
userIntent?.let { handleIntent(it) }
}.launchIn(viewModelScope)
}
abstract fun handleIntent(userIntent: I)
/**
* 驱动UI更新
*/
fun obtainUiState(): MutableLiveData<S> {
return mUiState
}
/**
* 延迟10ms重置状态,防止连续发送相同状态stateFlow没处理
*/
suspend fun sendUserIntent(userIntent: I) {
_userIntentFlow.tryEmit(userIntent)
delay(10)
_userIntentFlow.tryEmit(mNoneValueIntent)
}
}