mvi android라고 구글링 하면 양질의 자료들이 많다!
최근에 Android Developer의 권장 아키텍처의 설명을 보면
1. unidirection
2. state
3. immutable등의 키워드를 볼 수 있는데,
이게 나는 MVI를 설명하고 싶은 게 아닌가?라는 생각이 들었다.
그렇다면, 기존의 MVVM구조가 어떻길래 왜 MVI가 나오게 되나??
근데 나는 MVVM구조와 MVI가 아주 다른 구조라고 생각하지 않는다.
기존에 ViewModel의 사용법에서 ViewModel의 책임을 분산시키고,
유저의 이벤트에 대한 반응을 직관적으로 관리하기 위함?
정도라고 생각이 드는데... 일단 한번 알아보자..
MVVM에서 ViewModel내에는 View에 표현해 주기 위한 데이터들이 매우 많을 수 있다.
단순히 하나의 데이터만 보여주고 이를 업데이트하는 정도라면 별 효용성이 없을 수 있는데.
앱의 크기가 커지고 기능이 다양해지게 되면, livedata1,2,3,4.... 등등을 모두 ViewController가 옵저빙 해야 하고 이에 대한 이벤트들은 또 각각의 데이터를 변경시키면서 예상치 못한 뷰가 나타 날 수 있다.

위 와같이 매우 복잡해질 수 있는 구조를

이렇게 하나의 State로 관리하면 뷰를 표현하는 데이터는 ViewState단 하나로 관리가 쉬워진다.
그리고 이 State를 불변성의 데이터로 정의하고,
이 State변화는 오직 사용자의 Intent나 SideEffect에 의한 Event발생 -> 현재의 State와 발생한 Event의 결과로 새로운 State의 만으로 이루어지게 한다.
발그림으로 그리면

이런 느낌이려나...
SideEffet가 정확하게 뭘까 감이 잘 안잡히는데..
실시간 업데이트를 받는 Firebase AddSnapShotListener에 의한 데이터 업데이트 정도가 될까??
그래서 MVI를 사용하게되면서 장점이라고 한다면
1. 예측이 가능한 VIewState를 단 하나로 관리하므로 직관적임
2. 디버그 편리함
3. 공부를 해야해서 뭔가를 배울 수 있다..... 나는 Flow를 공부하게 되는 계기가 됨
이런 식으로 UI를 표현하기 위해서 MVI는 다른 지저분한 코드들이 필요하게 되고, 준비물? 이 더 필요하게 된다.
ViewModel을 MVIVideModel로 관리하는 코드들을 많이 봤는데, 아래의 코드가 가장 좋았던 것 같다.
abstract class MviViewModel<Event, Result, State, Effect>(initialState: State) : ViewModel() {
val states: StateFlow<State>
val effects: Flow<Effect>
private val events = MutableSharedFlow<Event>()
init {
events
.onSubscription {
println("check : ${events.subscriptionCount.value}")
check(events.subscriptionCount.value == 1)
onStart()
}
.share() // Share emissions to individual Flows within toResults()
.toResults()
.share() // Share emissions to states and effects
.also { results ->
states = results.toStates(initialState)
.stateIn(
scope = viewModelScope,
started = SharingStarted.Lazily,
initialValue = initialState
)
effects = results.toEffects()
}
}
fun processEvent(event: Event) {
viewModelScope.launch {
events.emit(event)
}
}
private fun <T> Flow<T>.share(): Flow<T> {
return shareIn(
scope = viewModelScope,
started = SharingStarted.Lazily
)
}
protected open fun onStart() = Unit
protected abstract fun Flow<Event>.toResults(): Flow<Result>
protected abstract fun Result.reduce(state: State): State
protected open fun Flow<Result>.toEffects(): Flow<Effect> = emptyFlow()
private fun Flow<Result>.toStates(initialState: State): Flow<State> {
return scan(initialState) { state, result -> result.reduce(state) }
}
}
그런데 최신의 Android Developer의 아키텍쳐에 관한 내용을 읽어보면,
위와같은 별도의 뷰모델을 만들기 보다는 그냥 UI State를 통해서 뷰를 관리하는 것을 알 수 있는데,
나도 굳이 위의 뷰모델의 과정이 필요한지 의문이 든다.
좀 더 많이 공부를 해서 이해를 해봐야 겠다.
'안드로이드 읽어보기 > 5. Android Architecture' 카테고리의 다른 글
4) Data Layer / Android Architecture 어떻게 해야하는가? (0) | 2022.04.19 |
---|---|
3) Data Layer 워밍업 / 안드로이드 아키텍쳐 (0) | 2022.04.19 |
Android Architecture은 어떻게 해야할까? (2) UI Layer (0) | 2022.03.16 |
MVVM이 무엇인가??? (0) | 2022.03.16 |
Android Architecture 어떻게 해야하는가?(1) (0) | 2022.03.15 |
mvi android라고 구글링 하면 양질의 자료들이 많다!
최근에 Android Developer의 권장 아키텍처의 설명을 보면
1. unidirection
2. state
3. immutable등의 키워드를 볼 수 있는데,
이게 나는 MVI를 설명하고 싶은 게 아닌가?라는 생각이 들었다.
그렇다면, 기존의 MVVM구조가 어떻길래 왜 MVI가 나오게 되나??
근데 나는 MVVM구조와 MVI가 아주 다른 구조라고 생각하지 않는다.
기존에 ViewModel의 사용법에서 ViewModel의 책임을 분산시키고,
유저의 이벤트에 대한 반응을 직관적으로 관리하기 위함?
정도라고 생각이 드는데... 일단 한번 알아보자..
MVVM에서 ViewModel내에는 View에 표현해 주기 위한 데이터들이 매우 많을 수 있다.
단순히 하나의 데이터만 보여주고 이를 업데이트하는 정도라면 별 효용성이 없을 수 있는데.
앱의 크기가 커지고 기능이 다양해지게 되면, livedata1,2,3,4.... 등등을 모두 ViewController가 옵저빙 해야 하고 이에 대한 이벤트들은 또 각각의 데이터를 변경시키면서 예상치 못한 뷰가 나타 날 수 있다.

위 와같이 매우 복잡해질 수 있는 구조를

이렇게 하나의 State로 관리하면 뷰를 표현하는 데이터는 ViewState단 하나로 관리가 쉬워진다.
그리고 이 State를 불변성의 데이터로 정의하고,
이 State변화는 오직 사용자의 Intent나 SideEffect에 의한 Event발생 -> 현재의 State와 발생한 Event의 결과로 새로운 State의 만으로 이루어지게 한다.
발그림으로 그리면

이런 느낌이려나...
SideEffet가 정확하게 뭘까 감이 잘 안잡히는데..
실시간 업데이트를 받는 Firebase AddSnapShotListener에 의한 데이터 업데이트 정도가 될까??
그래서 MVI를 사용하게되면서 장점이라고 한다면
1. 예측이 가능한 VIewState를 단 하나로 관리하므로 직관적임
2. 디버그 편리함
3. 공부를 해야해서 뭔가를 배울 수 있다..... 나는 Flow를 공부하게 되는 계기가 됨
이런 식으로 UI를 표현하기 위해서 MVI는 다른 지저분한 코드들이 필요하게 되고, 준비물? 이 더 필요하게 된다.
ViewModel을 MVIVideModel로 관리하는 코드들을 많이 봤는데, 아래의 코드가 가장 좋았던 것 같다.
abstract class MviViewModel<Event, Result, State, Effect>(initialState: State) : ViewModel() {
val states: StateFlow<State>
val effects: Flow<Effect>
private val events = MutableSharedFlow<Event>()
init {
events
.onSubscription {
println("check : ${events.subscriptionCount.value}")
check(events.subscriptionCount.value == 1)
onStart()
}
.share() // Share emissions to individual Flows within toResults()
.toResults()
.share() // Share emissions to states and effects
.also { results ->
states = results.toStates(initialState)
.stateIn(
scope = viewModelScope,
started = SharingStarted.Lazily,
initialValue = initialState
)
effects = results.toEffects()
}
}
fun processEvent(event: Event) {
viewModelScope.launch {
events.emit(event)
}
}
private fun <T> Flow<T>.share(): Flow<T> {
return shareIn(
scope = viewModelScope,
started = SharingStarted.Lazily
)
}
protected open fun onStart() = Unit
protected abstract fun Flow<Event>.toResults(): Flow<Result>
protected abstract fun Result.reduce(state: State): State
protected open fun Flow<Result>.toEffects(): Flow<Effect> = emptyFlow()
private fun Flow<Result>.toStates(initialState: State): Flow<State> {
return scan(initialState) { state, result -> result.reduce(state) }
}
}
그런데 최신의 Android Developer의 아키텍쳐에 관한 내용을 읽어보면,
위와같은 별도의 뷰모델을 만들기 보다는 그냥 UI State를 통해서 뷰를 관리하는 것을 알 수 있는데,
나도 굳이 위의 뷰모델의 과정이 필요한지 의문이 든다.
좀 더 많이 공부를 해서 이해를 해봐야 겠다.
'안드로이드 읽어보기 > 5. Android Architecture' 카테고리의 다른 글
4) Data Layer / Android Architecture 어떻게 해야하는가? (0) | 2022.04.19 |
---|---|
3) Data Layer 워밍업 / 안드로이드 아키텍쳐 (0) | 2022.04.19 |
Android Architecture은 어떻게 해야할까? (2) UI Layer (0) | 2022.03.16 |
MVVM이 무엇인가??? (0) | 2022.03.16 |
Android Architecture 어떻게 해야하는가?(1) (0) | 2022.03.15 |