MVVM
View는 최대한 멍청하게, ViewModel은 테스트 가능한 상태 머신처럼, Model은 비즈니스 규칙의 집합체처럼”
MVVM은 “패턴 자체가 목적”이 아니라 “변경 관리·테스트·협업 구조를 위해 쓰는 도구”
언제 쓰면 좋은가?
화면 수가 많고, 상태 복잡도가 높은 서비스(커머스, 물류, 금융 등)
디자이너/웹뷰/네이티브가 섞여 있고, 뷰 레이어 churn이 잦은 조직
TDD/단위테스트를 로직 레벨에서 제대로 가져가고 싶은 팀
MVVM의 구조
Model: 서버·DB·로컬에 있는 실제 데이터와 비즈니스 로직을 담당하는 레이어. 엔티티, Repository, UseCase 등이 여기에 온다고 보면 된다.
View: 화면에 보이는 UI 그 자체. 버튼, 텍스트, 리스트 같은 것들만 신경 쓰고, 비즈니스 로직은 최대한 안 넣는 게 원칙이다.
ViewModel: View가 쓸 수 있게 데이터를 가공해서 내놓고, View에서 오는 이벤트를 받아 Model 쪽에 전달하는 중간 레이어.
MVVM의 목적
변경 이유를 분리
View는 “UI/디자인 변경” 때문에 바뀌고, Model은 “비즈니스 정책·데이터 구조 변경” 때문에 바뀐다.
MVVM은 이 둘이 서로 직접 참조하지 않게 해서, 한쪽 변경이 다른 쪽에 ‘도미노’로 번지는 걸 줄이려는 구조다.
테스트 가능성 확보
ViewModel은 UI 프레임워크에 의존하지 않는, 그냥 평범한 객체로 설계하는 것이 이상적이다.
그래서 UI 없이도 단위 테스트로 상태 전이, 비즈니스 흐름을 검증할 수 있다.
데이터 흐름을 한 사이클로 보면
로그인 화면을 예로 들면:
사용자가 View에서 “로그인 버튼 클릭”
View는 이 이벤트를 ViewModel에 위임 (ex.
viewModel.onLoginClicked(id, pw)).ViewModel은 Model/Repository에 “로그인 시도” 요청을 보냄.
Model이 서버 호출·검증 후 결과를 ViewModel에 반환.
ViewModel은 결과를
uiState같은 형태로 가공해서 자신의 상태를 갱신.View는 ViewModel과 바인딩되어 있으므로,
uiState변화에 따라 자동으로 화면을 다시 그림 (성공/실패 메시지, 로딩 인디케이터 등).
핵심은: View는 “상태를 그리기만” 하고, “상태를 만들고 바꾸는 책임”은 전부 ViewModel에 몰아주는 것이다.
MVVM이 강조하는 원칙
View ↔ ViewModel 간 결합도 최소화
이상적인 MVVM에서는 ViewModel이 View의 존재를 몰라야 한다. View는 단지 ViewModel의 공개된 상태와 이벤트 메서드만 본다.
상태 기반 UI
“이벤트마다 UI 직접 제어”가 아니라, “이벤트 → 상태 변경 → 상태에 따라 UI가 자동으로 변함” 패턴을 강제한다.
그래서 ViewModel 설계를 사실상 상태 머신 설계처럼 가져가는 게 좋다.
데이터 바인딩 활용
전통적인 MVVM은 데이터 바인딩(Observer, Rx, LiveData, StateFlow 등)을 전제로 한다.
바인딩 덕분에 View가 ViewModel 필드를 계속 polling하지 않고, 변경 시에만 반응한다.
Last updated