ViewModel vs MVVM의 ViewModel 개념아래는 핵심 차이와 실무에서 어떻게 적용되는지 한눈에 보이도록 정리한 비교입니다.
Android (AAC) ViewModel
Android Jetpack의 ViewModel 클래스는 UI 관련 상태(screen-level state) 를 보관하고 구성 변경(예: 화면 회전) 동안 이를 유지해 주는 라이프사이클 인식 객체입니다. 또한 viewModelScope, SavedStateHandle 등 Android 환경 특화 도구와 함께 사용됩니다. (Android Developers)
(문서: https://developer.android.com/topic/libraries/architecture/viewmodel , API: https://developer.android.com/reference/androidx/lifecycle/ViewModel)
MVVM의 ViewModel (패턴 관점)
MVVM 패턴에서 ViewModel은 View와 Model 사이의 중간자로, 뷰에 표시할 데이터(포맷된 상태)와 뷰 로직(표시·명령)을 갖습니다. View와 직접 참조를 가지지 않으며 데이터 바인딩(또는 옵저버)을 통해 View를 갱신합니다. 패턴 자체는 플랫폼 중립적입니다. (Microsoft Learn, 위키백과)
(참고: Microsoft Learn MVVM 문서 등)
AAC ViewModel (구체적 책임)
SavedStateHandle 사용). (Android Developers)viewModelScope 사용(뷰모델 소멸 시 자동 취소). (Android Developers)MVVM ViewModel (개념적 책임)
AAC ViewModel
ViewModelStoreOwner(Activity, Fragment, NavBackStackEntry 등)에 스코핑되어 생성되고, 해당 소유자가 파괴될 때 onCleared() 호출되어 소멸됩니다. 따라서 동일한 ViewModel 클래스로도 서로 다른 ViewModelStoreOwner이면 별도 인스턴스가 생성됩니다. (NavGraph 단위로 공유 가능) (Android Developers, Stack Overflow)NavBackStackEntry를 ViewModelStoreOwner로 사용해 네비게이션 그래프 범위로 ViewModel을 공유할 수 있습니다. (Medium)MVVM ViewModel (패턴)
ViewModelStoreOwner). 패턴 차원에서는 “뷰와 독립된 프레젠테이션 상태”를 갖는다고 이해하면 됩니다. (Microsoft Learn)AAC: ViewModel 자체는 프로세스 종료 시 사라집니다. 프로세스 강제 종료 시 복원을 원하면 SavedStateHandle 또는 영속 스토리지(DB, preferences)를 사용해야 합니다. SavedStateHandle은 ViewModel 안에서 키-값 방식으로 간단히 저장·복원 가능. (Android Developers)
MVVM(일반): 패턴 차원에서의 상태 복원 방법은 프레임워크에 따라 다름(예: WPF의 바인딩 + 상태복원 로직 등).
viewModelScope를 이용해 ViewModel에서 코루틴을 시작하고, ViewModel 소멸 시 자동으로 취소되도록 관리합니다. ViewModel은 가능한 한 코루틴을 만들어 도메인(UseCase/Repository)을 호출하는 방식이 권장됩니다(도메인 로직은 도메인 레이어). (Android Developers)AAC ViewModel: AndroidX ViewModel은 일반 Kotlin 클래스이므로 리포지토리를 목(mock)으로 주입하면 단위 테스트 가능. 다만 SavedStateHandle이나 viewModelScope 관련 동작을 테스트 시 적절한 TestDispatcher/테스트용 SavedState 제공 필요. (Android Developers)
MVVM ViewModel(패턴): 패턴 자체는 테스트하기 쉬움(뷰와 로직 분리). 구체적 구현(플랫폼 API 의존성)을 줄이면 더 테스트하기 쉬움. (Microsoft Learn)
ViewModel (AndroidX)AndroidX ViewModel (예)
class MyViewModel(
private val repo: MyRepository,
private val savedStateHandle: SavedStateHandle
) : ViewModel() {
val uiState = MutableStateFlow<MyUiState>(MyUiState.Loading)
init {
viewModelScope.launch {
val data = repo.load()
uiState.value = MyUiState.Success(data)
}
}
fun onRefresh() {
viewModelScope.launch { /* 갱신 */ }
}
}
(핵심: viewModelScope, SavedStateHandle 사용). (Android Developers)
MVVM ViewModel(개념 예)
ViewModel 역할:
- UI가 필요한 데이터를 포맷해서 노출(exposedState)
- UI 이벤트를 수신해 명령 실행(예: onClick)
- 내부적으로 Model/Repository(또는 UseCase)를 호출
(실제로 Android에서 MVVM을 구현하면 위 MyViewModel이 MVVM의 ViewModel 역할을 수행함.)
“MVVM의 ViewModel과 Android ViewModel은 같은 것인가?”
패턴 관점에서는 역할이 겹칩니다(중간자, UI 상태 보유). 하지만 AndroidX ViewModel은 MVVM 패턴에서 ViewModel을 구현할 때 사용하는 구체적 클래스/도구입니다. 즉 MVVM의 개념 ←→ Android의 구현(도구). (Microsoft Learn, Android Developers)
“ViewModel에 모든 로직을 넣어도 될까?”
아니요. 단순 UI 로직은 ViewModel에, 복잡한 비즈니스 로직은 도메인 레이어(UseCase/Repository)로 분리하는 것이 유지보수·테스트에 유리합니다. (Android Developers)
“구성 변경(화면 회전)과 프로세스 종료는 다르다?”
예. ViewModel은 구성 변경은 자동으로 견디지만(재생성되지 않음), 프로세스 강제 종료 시는 사라집니다. 프로세스 종료 내성은 SavedStateHandle 또는 영속 저장이 필요합니다. (Android Developers)
📌 한 줄 요약
📋 핵심 차이
| 구분 | MVVM ViewModel | Android AAC ViewModel |
|---|---|---|
| 성격 | 패턴 개념 | Android 전용 구현체 |
| 기능 | UI 데이터 변환·노출, 이벤트 처리 | UI 상태 보관, 구성 변경 시 유지, viewModelScope, SavedStateHandle |
| 라이프사이클 | 프레임워크마다 다름 | ViewModelStoreOwner 범위(Activity, Fragment, NavGraph) |
| 범용성 | 플랫폼 무관 | Android 한정 |
즉, AAC ViewModel은 MVVM ViewModel의 Android 버전 실체라고 보시면 됩니다.