반응형
Notice
Recent Posts
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- socket-client
- JNI
- firebase-storage
- 워치
- BottomSheetDialog
- Firebase
- firebase-database
- git
- ozd
- ActivityResult-API
- mosquitto
- 오즈뷰어
- mqtt
- OZViewer
- Dva
- git-push
- hung-up
- cloud-firestore
- TIZEN
- Android
- Java8
- Kotlin
- Flavors
- socket.io
- AWS
- NoSuchMethodError
- Galaxy Watch
- google-login
- gradle
- socket-server
Archives
- Today
- Total
Hyeyeon blog
MVI Architecture Pattern in Android 본문
반응형
1. MVI 패턴이란?
MVI (Model-View-Intent) 패턴은 단방향 데이터 흐름을 기반으로 하는 아키텍처 패턴입니다.
사용자의 입력(Intent)을 받아 애플리케이션의 상태(State)를 변경하고, 그 상태를 기반으로 UI(View)를 렌더링하는 구조를 갖습니다.
이를 통해 복잡한 상태 관리를 단순화하고 UI의 동작을 예측 가능하게 만들어 디버깅과 유지보수를 용이하게 만듭니다.
2. Compose + MVI
1) 단방향 데이터 흐름
Compose의 UI는 상태(State)에 따라 변하며 상태 변화가 있을 때마다 UI가 재구성됩니다.
MVI는 단방향 데이터 흐름을 사용하여 상태를 관리하기 때문에 Compose의 흐름과 잘 맞습니다.
2) 불변 상태 관리
Compose는 상태를 불변(immutable)하게 관리하며, 상태가 변경될 때마다 새로운 상태 객체를 생성하여 UI를 업데이트합니다.
MVI 또한 상태를 불변 객체로 관리하며 상태 변화를 Intent를 통해 처리합니다.
3. MVI의 구성 요소
1) Model
- State와 State 업데이트 로직을 관리합니다.
2) View
- Model에서 전달받은 State를 기반으로 UI를 렌더링합니다.
3) Intent
- 사용자의 이벤트를 의미합니다. (ex: 버튼 클릭)
4) ViewModel (옵션)
- Intent를 처리하여 State를 업데이트 합니다.
ViewModel을 사용하지 않으면, Reducer 클래스에서 State를 업데이트합니다.
4. MVI 패턴의 장점
1) 단방향 데이터 흐름
- 데이터가 한 방향으로만 흐르므로 상태 관리가 명확해지고 디버깅이 용이합니다.
2) 상태 기반 UI
- View는 상태(State)만을 기반으로 UI를 렌더링하여 UI와 비즈니스 로직이 분리됩니다.
3) 불변성 (Immutability)
- 상태를 불변 객체로 관리하여 앱의 안정성이 높아집니다.
4) 테스트 용이성
- 비즈니스 로직과 UI가 분리되어 있어 ViewModel과 Model을 단위 테스트하기 쉬워집니다.
- Intent → State 변화 과정을 쉽게 테스트할 수 있습니다.
5. MVI 패턴의 단점
1) 복잡성 증가
- 단순한 앱에서는 과도한 아키텍처가 될 수 있습니다.
- 초기 세팅이 복잡하며 러닝 커브가 있습니다.
2) 성능 이슈
- 상태 업데이트가 많을 경우 불필요한 리렌더링이 발생하여 성능 저하가 발생할 수 있습니다.
- 최적화된 상태 관리 전략이 필요합니다.
6. MVI 패턴 구현 예제
버튼을 클릭하여 카운트업/다운 하는 예제입니다.
🔹 Step 1: Model 정의 (State)
data class CounterState(val count: Int = 0)
🔹 Step 2: Intent 정의
사용자 이벤트를 나타내는 Intent 클래스를 생성합니다.
sealed class CounterIntent {
object Increment : CounterIntent()
object Decrement : CounterIntent()
}
🔹 Step 3: ViewModel 구현
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
class CounterViewModel : ViewModel() {
private val _state = MutableStateFlow(CounterState())
val state: StateFlow<CounterState> = _state
fun processIntent(intent: CounterIntent) {
viewModelScope.launch {
when (intent) {
is CounterIntent.Increment -> _state.value = CounterState(_state.value.count + 1)
is CounterIntent.Decrement -> _state.value = CounterState(_state.value.count - 1)
}
}
}
}
🔹 Step 4: View 구현 (Jetpack Compose)
class MainActivity : ComponentActivity() {
private val counterViewModel: CounterViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MVIDemoTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
CounterScreen(viewModel = counterViewModel)
}
}
}
}
}
@Composable
fun CounterScreen(viewModel: CounterViewModel) {
val state by viewModel.state.collectAsState()
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(text = "Count: ${state.count}")
Spacer(modifier = Modifier.height(16.dp))
Row {
Button(onClick = { viewModel.processIntent(CounterIntent.Decrement) }) {
Text(text = "-1")
}
Spacer(modifier = Modifier.width(16.dp))
Button(onClick = { viewModel.processIntent(CounterIntent.Increment) }) {
Text(text = "+1")
}
}
}
}
728x90
'개발 > Android' 카테고리의 다른 글
이펙티브 코틀린 - 5장 객체생성, 6장 클래스 설계 (0) | 2024.04.09 |
---|---|
'compileDebugJavaWithJavac' task (current target is 1.8) and 'kaptGenerateStubsDebugKotlin' task (current target is 17) jvm target compatibility should be set to the same Java version. (0) | 2024.04.08 |
이펙티브 코틀린 - 3장 재사용성, 4장 추상화 설계 (0) | 2024.04.08 |
이펙티브 코틀린 - 2장 가독성 (0) | 2024.03.10 |
이펙티브 코틀린 - 1장 안정성 (0) | 2024.03.06 |
Comments