viewmodel이나 livedata를 말하기전에 이게 어디서 튀어나온건지 알기위해 app architecture에 대해 알아야한다. 더불어 Android에서 지원하는 Architecture Components도 간단하게 알아보자. 이 부분에 있어 잘 설명된 문서가 있으니 이것을 참조해도 좋다.
MVC 패턴
대부분 프로그램이 개발과정과 유지보수를 용이하게 하기위해 구조적 디자인패턴들을 이용한다. 여기서 가장 기본개념은 UI, DATA 그리고 비지니스 로직을 분리하는 것이다.
오랫동안 사랑받아온 디자인 패턴으로 MVC(model-view-controller)가 있다. model은 data를 다루는 부분으로 DB, filesystem, network등을 통해 데이터를 저장하고 가져오는 역할을 한다. android에서는 jetpack 이전에 특별히 지원하진 않았었지만, sqlite db사용이 가능했고, content provider로 중앙집중식 데이터 관리를 지원해서 이들에 대한 인터페이스 또는 네트웍으로 리모트 데이터 전송파트를 만드는 작업이 이에 해당해왔다.
view는 UI를 말하며, data와 독립적으로 화면구성을 지원한다. android에선 UI xml들이 이에 해당한다.
controller는 비지니스 로직에 해당하며, View로부터 사용자의 입력을 받아 Model이 가진 데이터를 다루거나, 리모트 네트워크로부터의 응답을 처리하는등의 역할을 한다. android 에서 jetpack 지원 architecture를 사용하지 않는다면 activity class, fragment class 등 layout xml에 대응하는 클래스들이 이에 해당한다.

아마도 어떤사람들은 MVC에 대응하는 android 파트에 동의하지 않을것이다. 왜냐하면 정확히 1:1로 매칭이 되지 않기 때문이다. activity나 fragment class들이 UI와 강하게 결합되어 있어서 UI로 분류할수도 있다. 이 부분은 개발자가 어떻게 다룰지에 따라 결정되는 부분이다.
MVC 패턴의 문제점이라면, controller에 점점 더 많은 코드들이 집중된다는 사실과 UI와 뒤섞일 가능성이 높다는 점인데, android의 activity나 fragment의 경우 UI와 강한 결합을 갖고있기에 이를 더 복잡하게 만든다.
MVP 패턴
이러한 안드로이드의 문제를 개선하려면 MVP(Model-View-Presenter)를 사용하기도 한다. 이 경우, activity나 fragment 클래스들은 자연스럽게 View에 속하게되며, 단순 인터페이스형태로 presenter를 별도로 만들어야 한다. Model로부터 데이터 변경은 MVC에서처럼 직접 View로 전달되지 않고, Presenter를 통해 전달된다. Presenter는 View의 모습에 관여하지 않고, 보여줄 data만 전달하게되어, View와 독립된 controller로서의 역할에 충실한 모델이라고 생각할 수 있다.
MVVM 패턴
MVC 모델이 오랜기간 사랑받으며 사용되어 왔으나, 이를 개선하려는 노력들도 있어왔다. 영문 위키 히스토리항목 참조. MVA(Model-View-Adapter), MVP(Model-View-Presenter), MVVM(Model-View-ViewModel) 등. 각각 구현환경에 따라 진화해 나갔다. 안드로이드에선 구조적 문제해결을 위해 MVP모델의 진화형태인 MVVM 패턴을 선택한 것으로 보인다.
우선 위키문서를 참조해보자.

MVC의 개선모델인 MVP가 더 진보한 것으로 MVP와의 비교가 더 쉬울 것이다. Model과 View는 MVP에서와 거의 동일하다. Presenter 부분에 ViewModel이 들어가고, View와는 인터페이스 대신에, DataBinding으로 연결된다. DataBinding이란건, View에서 표시할 데이터가 ViewModel에 Binder로 직접 연결되어 있다고 생각하면 된다. 데이터를 표시할 때, ViewModel의 데이터를 읽어와서 표시하며, Data변경이 이루어지면, ViewModel에서의 값 변경을 View에서 Observer 패턴으로 모니터링 하다가 변경된 값을 적용하게 된다.
Android에서는 Jetpack 라이브러리를 통해 MVVM을 지원한다. DataBinding이 용이하도록 XML 기능을 확장했고, ViewModel 클래스를 지원한다. 또한, LiveData를 통해 Data Binding의 Observer 패턴을 지원한다. LiveData는 간단히 언급하자면, Observable data wrapper정도다. Model 부분 지원을 위해서는 Database를 보다 쉽게 사용하도록 Room 라이브러리를 제공한다.
Android에서 MVVM 패턴을 적용하면, activity 나 fragment 클래스는 명확하게 View에 포함시켜 기존의 애매모호함이 사라지며, ViewModel은 View에 대한 의존성이 거의 없으므로 더 좋은 구조가 된다.
이전에 가장 큰 문제중 하나로 화면 rotation이슈가 있다. rotation시 View가 Destroy되고 다시 Create되게되며 View를 따라 Activity, Fragment 클래스들도 같이 Destroy되며 이전 데이터를 유지하지 못하는 문제가 있다. onSaveInstanceState()와 같은 함수로 데이터를 저장, 복원하도록 구현되어 있지만, Activity, Fragment 클래스들이 View에 종속되는 가장 큰 이유중 하나였다. MVVM 패턴에선 데이터들이 ViewModel에 존재하고, ViewModel은 rotation에 무관하게 유지되며 완전히 finished 됐을 때만 onCleared()가 불리며 종료되기 때문에 문제가 깔끔하게 해결된다. 공식문서에 나와있는 라이프사이클을 보면 다음과 같다.

AAC(Android Architecture Component)
그럼, MVVM을 Android가 어떻게 지원하고 있는지 알아보자. Android에서는 Jetpack 라이브러리로 앱 개발을 좀 더 쉽게 할수있도록 지원하고 있다. 그 일부로 Architecture component들을 지원한다. 이 컴포넌트들중에 MVVM모델을 지원하고 있다. 세부적으로는 LiveData와 ViewModel을 포함한 Lifecycle component, SQLite 래퍼인 Room 정도가 이에 해당된다.
라이브러리로 제공하므로, gradle 파일에 repository와 library가 추가되어야 한다. repository는 google을 이용하므로 딱히 추가가 필요하지는 않다.
allprojects {
repositories {
google()
jcenter()
}
}
각 컴포넌트의 추가는 라이브러리 문서를 참고해서 추가한다. lifecycle 문서를 예로들면, viewmodel과 livedata만 포함시키는 경우 다음을 추가하는 것으로 충분하다.
dependencies {
def lifecycle_version = "2.2.0"
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
...
App Architecture
공식문서의 Guide to app architecture에 이 모든게 상세히 기술되고 있다. 여기에서 권장하는 앱의 구조는 다음과 같다.

위 그림은 MVVM 모델을 표현하고 있다. Activity/Fragment가 View이고 LiveData를 이용하여 ViewModel과 Data binding으로 연결되어 있으며, Room 및 리모트 데이터 엑세스 방법으로 Model을 표현하고 있다. 상세한 내용을 알고 싶다면, 공식문서의 가이드를 참고바란다.
기본적인 배경은 대충 알게된거 같으니, 추가 포스팅으로 ViewModel 과 LiveData에 대한 정리를 해보자.