MVC (Model-View-Controller)
Model
UI와 독립적인 요소로 data를 다룸. 상태 변화가 있을 때 Controller와 View에 통보하며, 이를 통해 최신 상태를 유지함. 통보 대신 View나 Controller가 직접 Model의 상태를 읽기도 함.
View
사용자가 볼 수 있도록 표현하기 위해 Model로 부터 정보를 얻어옴
Controller
입력을 받아 Model 또는 View에 대한 명령으로 변환(처리)
특징
- View는 Model에 정보를 요청하고, Model은 addObserver 함수로 View를 등록하고, Model에 상태가 바뀌면 notify하여 View 갱신.
- Model은 여러 개의 View를 가질 수 있고, View도 여러개의 Model에 등록할 수 있음.
- View와 Model 사이 의존성이 있음
MVP (Model-View-Presenter)
Model
보여줄 데이터나 ui에 사용 되는 데이터
View
수동적인 interface로 data를 보여주고 사용자의 이벤트를 Presenter에 알림
Presenter
Model과 View와 함께 동작하고, Repository에서 데이터를 불러 View에 보여질 형태로 가공해서 View에 전달
특징
- View와 Model 사이 의존성 없음
- View 와 Presenter 는 1:1 관계를 가지며 결합도가 높음
- View 는 완전히 수동적: 모든 상호작용은 Presenter 에서 일어남
> View는 사용자 이벤트를 받으면 parameter도 없고, return 값도 없는 Presenter의 method를 호출
> Presenter는 View interface 를 통해 View의 데이터를 가져옴
> Presenter는 Model을 변경하고, 작업 결과로 View 업데이트
MVVM
Model
content의 실제 상태를 나타내거나 data access layer를 나타냄
View
MVC, MVP에서와 동일
ViewModel
공용 속성과 명령(method)를 노출하는 뷰의 추상화, MVC의 Controller나 MVP의 Presenter 대신 MVVM은 binder를 가짐. binder는 view와 바인딩 된 속성 사이의 상호작용을 자동화하는 역할을 함.
MVP의 Presenter와의 주된 차이점은 Presenter는 View의 Reference를 가지는 반면 Viewmodel은 갖지 않는다는 것. 대신 View는 바로 Viewmodel의 속성에 바인드해서 변경 사항을 수신함.
Android App Architecture
Principles
- Separation of concerns — Activity/Fragment에는 UI와 OS 상호작용을 다루는 로직만 포함
- Drive UI from a modle — Model은 data를 다루는 요소로, View와 App Component로부터 독립적
Repository
서로다른 data source 로 부터 데이터를 불러오는 mediator
ViewModel
lifecycle을 고려한 방식으로, UI와 관련된 데이터를 저장하고 관리하기 위해 설계됨. 특정 UI 컴포넌트에 대한 data를 제공하고 model과 상호작용을 위해 data-handling business logic을 가짐. UI Component에 대해서 몰라야 configuration 변경에 영향을 받지 않음.
Android ViewModel이 고안된 이유
- 1. system이 Activity/Fragment와 같은 UI Controller를 destroy 하고 re-create하면 UI 관련 데이터가 손실됨.
예를 들어 Activity 의 configuration이 변경된 경우 새 Activity에서 다시 데이터를 가져와야 함. 간단한 데이터의 경우 Activity는 onSaveInstanceState() 메소드를 사용하고, onCreate() 에서 데이터를 복원할 수 있지만 serialize 후 deserialize 할 수 있는 소량의 데이터에만 적합함. - 2. UI Controller가 빈번하게 비동기 호출이 필요한 경우 UI Controller에서 관련 작업이 필요하고, 잠재적인 memory leak을 피하기 위해 system이 이 데이터를 정리한 후 UI Controller가 destroy되도록 해야함
- Activity나 Fragment 같은 UI Controller는 기본적으로 UI data를 보여주고, 사용자의 액션에 반응하고, permission 요청과 같은 OS와 상호작용을 다룸. 추가적으로 database나 network에서 data를 불러오는 역할도 하고 있어 코드가 비대해지고 과도한 책임이 주어져 테스트가 어려워짐
> ViewModel을 사용하여 UI Controller에서 View data 소유권을 분리
MVI
Model
단방향 데이터 흐름을 보장하기 위해 immutable 이어야함.
View
Intent
intention이나 수행되길 바라는 action을 표현. 모든 action에 대해서 View는 Intent를 받음. Presenter는 Intent를 observe하고 Model을 새로운 상태로 변환함.
등장 배경
- Multiple Inputs: MVP의 Presenter, MVVM의 ViewModel은 종종 많은 입력과 출력을 관리, 이는 백그라운드 작업이 많은 큰 앱에서 문제가 됨.
- Multiple States: MVP와 MVVM에서 business logic과 View는 어떤 시점에 다른 상태를 가질지도 모름. 이를 위해 Observable 과 Observer callaback으로 상태에 대한 동기를 맞춰줘야 하는데 충돌이 있을 수 있음.
- View → Presenter →Business Logic → View
View: user action을 observing / Model을 표현
Presenter: data 관리
Business Logic: 다른 상태를 가지는 새로운 Model 생성
이점
- Single State: immutable data는 다루기 쉽고 한 곳에서만 관리 됨.
- Thread Safety: 어떤 메서드도 Model을 변경할 수 없기 때문에 항상 새로 생성되고 유지됨. 이는 다른 스레드에서 Model 객제를 수정하는 side effect를 방지할 수 있음.