PE Notes · SW
MVC, MVVM, MVI
관심사를 나눈 UI 패턴 세 가지의 데이터 흐름을 비교하고, 컨트롤러 비대·데이터 바인딩·단방향 불변 상태가 가르는 지점을 정리합니다.
화면과 업무 규칙이 한 파일에 있으면 수정·시험·재사용이 같이 무거워집니다. 관심사 분리가 UI 패턴의 목적입니다. 는 입력을 컨트롤러가 받고, 은 바인딩으로 화면을 맞추며, 는 한 방향으로만 상태를 바꿉니다.
MVC는 중재자가 비대해진다
Model은 데이터와 규칙, View는 그림, Controller는 입력·갱신·뷰 선택입니다. 사용자가 컨트롤러에 말하고, 컨트롤러가 모델을 고치고, 뷰가 그립니다. 서버 쪽 Spring MVC·Rails·Django가 이 줄입니다.
뷰가 모델을 직접 보기도 해서 결합이 남을 수 있습니다. Massive View Controller가 한계의 이름입니다. 테스트는 컨트롤러와 뷰가 붙어 있으면 어렵습니다.
| 구성 | 역할 |
|---|---|
| Model | 데이터·업무 규칙 |
| View | 화면 |
| Controller | 입력 처리, 모델 갱신, 뷰 선택 |
MVVM은 바인딩이 동기화한다
ViewModel은 화면용 상태를 준비하고 View를 가리키지 않습니다. View는 명령을 넘기고, 관찰한 값이 바뀌면 그려집니다. 이 그 자동 맞춤입니다. Android ViewModel+LiveData/StateFlow, SwiftUI, Angular, Vue, WPF가 이 자리입니다.
흐름은 View → ViewModel(명령) → Model, 그리고 관찰 가능한 상태가 다시 View로 옵니다. 양방향처럼 보이지만 참조 방향은 ViewModel→View가 아닙니다. 단점은 작은 화면에 부품이 많고, 바인딩 오류를 추적하기 어렵다는 점입니다.
MVI는 한 줄로만 흐른다
Intent는 클릭·검색 같은 의도입니다. Processor/Reducer가 현재 상태와 Intent로 새 상태를 계산합니다. View는 그 불변 상태를 그릴 뿐입니다. 입니다. React+Redux, Android MVI, Flutter BLoC과 같은 원리입니다.
상태는 수정하지 않고 새 객체를 만듭니다. 이전 스냅샷이 남아 시간 여행 디버깅이 됩니다. 예측과 로그는 강해지고, 보일러플레이트는 늘어납니다.
| 비교축 | MVC | MVVM | MVI |
|---|---|---|---|
| 흐름 | 양방향 | 바인딩 (양방향처럼) | 단방향 |
| 상태 | 분산 | ViewModel | 불변 단일 State |
| 시험 | 낮음 | 중간 | 높음 |
| 예측 | 낮음 | 중간 | 높음 |
| 보일러플레이트 | 낮음 | 중간 | 높음 |
| 자리 | 서버 웹 | 모바일·데스크톱 | 복잡한 반응형 |
REST API는 MVC, 일반 모바일은 MVVM, 상태 전이가 많은 화면은 MVI가 자주 맞습니다. 시큐어 코딩은 입력 검증을 컨트롤러·인텐트 입구에 두고, 라이선스는 가져오는 UI 부품에 붙습니다. 보일러플레이트는 바이브 코딩이 초안을 쓸 수 있으나, 흐름의 방향은 사람이 정합니다.