KOTLIN · 디자인패턴
MVI 패턴
Model-View-Intent 패턴으로 단방향 데이터 흐름을 구현합니다. 상태 관리가 예측 가능하고 디버깅이 쉽습니다.
디자인패턴고급mviunidirectionalreducerstate-management
핵심 설명
Model-View-Intent 패턴으로 단방향 데이터 흐름을 구현합니다. 상태 관리가 예측 가능하고 디버깅이 쉽습니다.
Kotlin code
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
// State
data class CounterState(val count: Int = 0, val loading: Boolean = false)
// Intent (사용자 액션)
sealed class CounterIntent {
data object Increment : CounterIntent()
data object Decrement : CounterIntent()
data object Reset : CounterIntent()
}
// Store (Reducer)
class CounterStore {
private val _state = MutableStateFlow(CounterState())
val state: StateFlow<CounterState> = _state.asStateFlow()
private val _intents = MutableSharedFlow<CounterIntent>()
suspend fun processIntents() {
_intents.collect { intent ->
val current = _state.value
_state.value = reduce(current, intent)
}
}
private fun reduce(state: CounterState, intent: CounterIntent): CounterState =
when (intent) {
CounterIntent.Increment -> state.copy(count = state.count + 1)
CounterIntent.Decrement -> state.copy(count = state.count - 1)
CounterIntent.Reset -> CounterState()
}
suspend fun dispatch(intent: CounterIntent) {
_intents.emit(intent)
}
}
fun main() = runBlocking {
val store = CounterStore()
launch { store.processIntents() }
val job = launch { store.state.collect { println("상태: $it") } }
store.dispatch(CounterIntent.Increment)
store.dispatch(CounterIntent.Increment)
store.dispatch(CounterIntent.Decrement)
delay(50)
store.dispatch(CounterIntent.Reset)
delay(50)
job.cancel()
}학습 팁
MVI의 reducer는 순수 함수이므로 단위 테스트가 매우 쉽습니다. 이전 상태 + Intent → 새 상태를 검증하면 됩니다.
주의할 점
reducer 내에서 부수 효과(API 호출 등)를 수행하지 마세요. 부수 효과는 미들웨어나 별도 계층에서 처리해야 합니다.
자주 묻는 질문
MVI 패턴란 무엇인가요?
Model-View-Intent 패턴으로 단방향 데이터 흐름을 구현합니다. 상태 관리가 예측 가능하고 디버깅이 쉽습니다.
MVI 패턴 학습 시 주의할 점은 무엇인가요?
reducer 내에서 부수 효과(API 호출 등)를 수행하지 마세요. 부수 효과는 미들웨어나 별도 계층에서 처리해야 합니다.
Continue Learning
Kotlin 학습을 이어가세요
총 200개의 독립 HTML 학습 문서 중 하나입니다. 각 문서는 고유 URL과 canonical 메타데이터를 가집니다.