돌고 돌아 다시 안드로이드로 돌아왔다.
우리의 코드인듯 아닌듯한 아이를 분석하면서
프로젝트에 적용된 MVVM 패턴에 대해 정확히 학습해보고,
올해 클론코딩을 진행했던 "배달의 민족" 앱에 적용할 계획이다 ! 💫
MVVM 에 대한 본격적인 분석에 앞서
많이 사용되는 디자인 패턴 MVC/MVP 도 살펴보고 가자
아자자
MVC vs MVP vs MVVM
안드로이드 앱을 논리적 구성 요소들로 체계화하려는 노력은 지속되어왔다.
가장 기초적인 MVC (Model-View-Controller) 패턴으로 시작하여
더 모듈화되고 테스트 가능한 패턴으로 발전해왔다.
MVC 를 대체하기 위해 가장 많이 쓰이는 두 가지 대안책으로
MVP (Model-View-Presenter) 와 MVVM (Model-View-ViewModel) 이 있다.
MVVM 에 앞서 MVC 와 MVP 패턴에 대해 살펴보자.
(1) MVC
프로그램을 각각의 역할에 따라 Model, View, Controller 로 나누어 설계한 아키텍쳐 패턴
- Model : 데이터 로직 담당 (데이터 처리)
- View : 사용자의 화면 담당 (UI 처리)
- Controller : 비즈니스 로직 담당 (사용자 이벤트 처리)
1. 모든 입력(input)들은 Controller 로 전달된다.
2. Controller 는 입력에 해당하는 Model 을 업데이트한다.
3. 업데이트 결과에 따라 View 를 선택한다.
(하나의 Controller 는 View 를 선택할 수 있기에 1:N 관계로, 여러 개의 View 를 관리할 수 있다.)
4. Controller 는 View 를 선택만 할 뿐, 직접 업데이트하지는 않는다.
(View 는 Controller 를 알지 못한다.)
5. View 를 업데이트하기 위해서는 아래와 같은 방법들이 있다.
- View 가 Model 을 직접 이용하여 업데이트
- Model 에서 View 에서 Notify 하여 업데이트
- View 가 Polling 하여 Model 의 변화를 감지하여 업데이트
View 를 업데이트하기 위해서는 결국 M-V 사이에 의존성이 존재하게 된다.
View 에서 Model 을 직접 참조하게 되어 앱이 커지고 유지보수가 힘들어진다.
웹에서 적용되는 MVC 패턴은 View 와 Controller 가 모두 분리된 상태이지만,
안드로이드는 Activity/Fragment 가 Controller 와 View 모두 처리하기 때문에
한 클래스에서 M-V-C 모두 처리하게 되는 문제점이 발생한다.
(2) MVP
MVC 에서 파생된, Model 과 View 간의 의존성이 없는 아키텍쳐 패턴
- Model : 내부적으로 사용하는 데이터를 저장/처리하는 역할
- View : 화면에서 발생하는 이벤트를 감지하고, UI 처리를 Presenter 에게 요청
- Presenter : View 로부터 요청받은 이벤트를 처리하고, 처리한 결과를 View 에게 전달 (인터페이스)
1. 모든 입력 (input) 들은 View 로 전달된다.
2. Presenter 는 입력에 해당하는 Model 을 업데이트한다.
3. Model 업데이트 결과를 기반으로 View 를 업데이트한다.
4. Presenter 는 해당 View 를 참조하고 있다.
(Veiw 와 Presenter 는 1:1 관계이다.)
5. Presenter 는 View 와 Model 인스턴스를 가지고, Model 과 View 사이의 매개체 역할을 한다.
MVC 와는 다르게 UI (View) 와 비즈니스 로직 (Model) 을 분리하고,
서로 간에 상호 작용을 다른 객체 (Presenter) 에 그 역할을 줌으로써 서로의 영향 (의존성) 을 최소화한다.
하지만 앱이 커지거나 복잡해질수록 V-P 간 의존성이 강해지는 문제점이 발생한다.
MVVM
MVC 에서 파생된, Model 과 View 간의 의존성뿐만 아니라 Controller 와 View 간의
의존성도 고려하여 각 구성 요소가 독립적으로 작성되고 테스트될 수 있도록 설계된 아키텍쳐 패턴
- Model : MVC 의 Model 과 동일한 역할
- ViewModel 에서 데이터를 가져갈 수 있게 데이터를 준비하고 그에 대한 이벤트를 보냄
- View : 레이아웃을 정의함
- ViewModel 을 관찰하고 있다가 상태 변화가 전달되면 화면을 갱신해야 함
- ViewModel : View 와 Model 사이의 매개체 역할
- View 와 관련된 비즈니스 로직이 들어가며 데이터를 가공해 View 에 뿌리기 쉬운 Model 로 바꾸는 역할
- View 가 데이터 바인딩 (DataBinding) 할 수 있는 속성과 명령으로 구성되어 있음
1. 모든 입력 (input) 은 View 로 전달된다.
2. ViewModel 은 입력에 해당하는 Presentation Logic 을 처리하여 View 에 데이터를 전달한다.
3. ViewModel 은 View 를 참조하지 않기 때문에 독립적이다.
(ViewModel 과 View 는 1:N 관계이다.)
4. 따라서 View 는 자신이 이용할 ViewModel 을 선택해 바인딩하여 업데이트를 받게 된다.
(Command 패턴이나 Data Binding 을 이용해 V-VM 간 의존성을 없앨 수 있다.)
5. Model 이 변경되면 해당하는 ViewModel 을 이용하는 View 가 자동으로 업데이트된다.
6. ViewModel 은 View 를 나타내주기 위한 Model 이자, View 의 Presentation Logic 을 처리한다.
MVP 와 마찬가지로 M-V 사이의 의존성이 없고,
MVP 처럼 V-VM 이 1:1 관계가 아닌 독립적이기 때문에 이 둘 사이의 의존성도 없다.
+α
(1) Jetpack
여러 라이브러리들이나 여러 툴들을 묶어놓은 모음집
즉, 안드로이드 래발자들이 더욱 쉽게 고퀄리티의 앱을 개발할 수 있도록 도와주는 라이브러리들의 모음집
Jetpack 에 포함되는 라이브러리들은 androidx.* 이름으로 패키지화되어 있고,
안드로이드 플랫폼 API 로부터 분리되어있다.
Jetpack 에 속한 많은 라이브러리들은 Android KTX extensions 를 지원한다.
* Android KTX? 안드로이드 프레임워크 API, Android Jetpack 라이브러리 등을 위한 확장 프로그램 집합
(2) AAC
💌 Github - Android Architecture Components Samples
Android Architecture Component (Jetpack 에 포함되는 구성요소의 일부분)
앱 아키텍쳐 가이드에서 권장하는 형태의 앱을 개발하기 위해 사용되는 라이브러리들의 집합
- Room, Lifecycles, ViewModel, LiveData, Paging, Navigation, DataBinding, WorkManager
(3) Android Clean Architecture
첫번째 원칙 ! UI 기반 클래스를 가볍게 하라
= UI 기반 클래스에서는 수명 주기에 따라 발생할 수 있는 상황에 대처하는 코드만 작성
두번째 원칙 ! UI 와 Model 을 분리하라
= UI 기반 클래스에 데이터나 상태를 저장하지 말라
아래 구조가 안드로이드에서 권장하는 아키텍쳐 이다.
각 구성요소들은 딱 한 단계 아래의 구성요소에만 종속되어있다.
(4) LiveData
💌 Android Developers - LiveData (Jetpack 구성요소)
관찰 가능한 데이터 홀더 클래스, 데이터 클래스를 잡고 있는 클래스
Activity/Fragment/Service(LiveData를 관찰하고 있는 Observer) 등의 수명 주기를 자체적으로 인식한다.
관찰자의 수명 주기가 stated 혹은 resumed 상태이면 LiveData 는 관찰자를 active 상태로 간주한다.
📌 LiveData 사용 단계
1. 특정 유형의 데이터를 홀드할(잡고있을) LiveData 인스턴스를 생성한다.
2. onChanged() 메소드를 정의하는 Observer 객체를 생성한다.
이 메소드는 LiveData 가 보유한 데이터가 변경될 시 발생하는 작업을 제어한다.
( 일반적으로 activity/fragment 같은 UI 컨트롤러에 Observer 객체를 생성함으로써 행해짐)
3. observe() 메소드를 사용해 LiveData 에 Observer 를 연결한다.
( observe 메소드는 LifecycleOwner를 사용하고,
이로 인해 Observer 가 LiveData 를 구독해 변경사항에 관한 알림을 받을 수 있음)
(5) ViewModel
💌 Android Developers - ViewModel
Activity/Fragment 같은 UI 에 데이터를 제공하고, Model 과 커뮤니케이션하기 위한 데이터 처리 비즈니스 로직
UI 기반 클래스가 아닌 일반 클래스이기에 UI 에 대해 모른다.
(Activity/Fragment 수명주기 변경에 영향을 받지 않음)
LiveData 를 사용해 UI 에게 데이터가 준비되었다고 알려준다.
View, 즉 UI 기반 클래스에서 ViewModel 클래스에 존재하는 LiveData 를 관찰하여
LiveData 신호를 알아차린다.
© 예제
(1) Tic-Tac-Toe 게임 (Github) (Blog)
(2) Room+LiveData+ViewModel 토이프로젝트 (Github) (Blog)
- ViewModel 을 이용한 MVVM 을 적용해 Room 에 간단한 데이터를 저장하고
LiveData 로 실시간 데이터 처리를 진행함 - UI 기능에 따른 디렉토리 => 아키텍쳐 기능에 따른 디렉토리
- Corutine
(3) 안드로이드 MVVM 패턴 빵들 (Github)
- DI Koin 을 이용한 기본 MVVM 패턴 빵들
- TextView & Button using ViewModel, LiveData and DataBinding
- RecyclerView using Retrofit, Koin, ViewModel
© 참고
https://academy.realm.io/kr/posts/eric-maxwell-mvc-mvp-and-mvvm-on-android/ (종합 안내서)
https://brunch.co.kr/@oemilk/113 (MVC, MVP, MVVM, MVI)
'Android > study' 카테고리의 다른 글
[Android] WebView 쿠키에 관하여 ... 🍪 (0) | 2021.11.25 |
---|---|
[Android] WebView (+ Chrome Custom Tabs) (0) | 2021.11.22 |
[Android Studio] 이미지 로딩 라이브러리 Glide 사용하기 (0) | 2021.09.17 |
[Android] 안드로이드 이벤트 (0) | 2021.09.07 |
[Android] 인텐트의 정의와 종류 (+ 플래그) (0) | 2021.09.02 |