[Android] AAC - ViewModel ( + vs MVVM의 ViewModel)

ENAN·2021년 6월 25일
0

ViewModel 개요

우선 MVVM 패턴 관점에서와 AAC 라이브러리로서의 ViewModel을 구분해 작성하려 한다.

MVVM 관점에서는 viewModel이 어떤 역할을 하는지와 같은 개념적인 얘기를 다루고, AAC 라이브러리 관점에선 이 viewModel이 안드로이드에서 어떻게 구현되었는지, 구체적인 사용 방법 등에 대해 적어보겠다.

👇 MVVM 패턴에 대해 잘 모른다면 아래의 글을 참고하면 좋을 듯! 👇
blog.yena.io/studynote/2019/03/16/Android-MVVM-AAC-1.html

위의 글을 읽고 왔다면 MVVM 패턴에 대해 대략적으로 이해가 되었을 것이다. 생명주기에 따른 데이터 관리나 유지보수 및 테스트 용이 등 여러 장점이 있지만, 이 글에서는 UI / 비즈니스 로직(+데이터) 의 역할 분리에 초점을 맞출 것이다. MVVM은 UI와 로직, 데이터를 어떻게 분리할까? 그 부분을 이해하기 위해, ViewModel의 역할을 좀 더 살펴보자.

ViewModel이란? - MVVM

ViewModel은 MVVM(Model - View - ViewModel) 패턴에서 View를 표현하기 위한 모델이자 이에 필요한 데이터 처리를 담당하는 부분이다. 즉, 뷰에서 필요로 하는 데이터와, 뷰와 관련된 비즈니스 로직을 갖고 있다.

ViewModel은 View가 필요로 하는 데이터만을 소유한다. 뷰는 이 데이터를 관찰(Observing) 하고 있다가 데이터의 변경이 감지되면 화면을 갱신시킨다. 또한 View가 UI 로직만 신경쓸 수 있도록 데이터 처리 로직은 ViewModel이 담당한다. 이러한 방식으로 ViewModel은 UI와 비즈니스 로직을 깔끔하게 분리한다.


그러면 안드로이드 개발 환경에서의 얘기로 넘어와 보자.

MVVM 패턴을 적용하면 Activity나 Fragment가 UI 관련 로직만 담당하고, ViewModel 클래스에는 뷰에 필요한 데이터와 비즈니스 로직을 둘 수 있다. 이렇게 개발하면 Activity나 Fragment같은 UI Controller 역할의 클래스들이 거대해지는 것을 방지할 수 있고, 유지보수, 테스트가 용이해질 수 있다. 또한 여러 View에서 ViewModel을 재사용함으로써 비즈니스 로직의 재사용성을 높일 수 있다.

이러한 장점으로 인해, 구글은 공식적으로 가이드에서 MVVM 패턴을 권장하고 있는 것 같다. 개발자들이 MVVM 패턴으로 쉽게 개발할 수 있도록 AAC와 같은 라이브러리들을 제공하는데, 그러면 AAC에서 제공하는 ViewModel 라이브러리도 이 MVVM 패턴에서 말하는 ViewModel을 위해 지원하는 걸까?

ViewModel이란? - AAC

AAC의 viewModel은 수명 주기를 고려해 관련 데이터를 저장하고 관리하도록 설계된 클래스다.

이 ViewModel을 사용하면 기존의 Activity가 생명 주기때문에 데이터 관리 면에서 겪던 어려움들을 간단하게 처리할 수 있다. 뷰모델의 생명 주기는 👇 아래의 그림과 같은데, 액티비티가 만들어지고 파괴되기 전까지 계속해서 살아있는 모습을 볼 수 있다. 그렇기 때문에 화면을 회전해서 Configuration Change가 일어나는 등 뷰가 파괴되고 새로 만들어지는 과정에서 데이터를 보존할 수 있다.

짚고 넘어갈 점은, 공식 문서를 읽어보면 어디에도 MVVM에 대한 내용은 찾아볼 수 없다. 즉, 단순히 viewModel은 컴포넌트들의 생명 주기에 따라 상태 정보나 데이터를 관리하기 쉽도록 사용하는 클래스이지, 사용한다고 MVVM 패턴으로 개발한다고는 말할 수 없다는 것이다.

물론 MVVM으로 개발할 때에 이 ViewModel 클래스를 사용하는 것이 도움이 된다고는 말할 수 있다. 그렇다면 ViewModel 클래스를 활용해 MVVM에서 말하는 ViewModel을 구현하려면 어떻게 해야 할까?


우선 ViewModel의 역할제약을 잘 이해하고 있어야 한다. ViewModel의 역할은 View에 필요한 데이터를 제공하고, 비즈니스 로직을 담당해 데이터를 처리하는 것이다. 즉 View와 Model의 사이에서 다리 역할을 해주는 매개체라고 볼 수 있다.

이 역할을 잘 수행하기 위해서 viewModel은 view를 참조하지 않아야 한다는 제약을 이해하고 지켜야 한다. view를 참조하는 순간 viewmodel이 특정 view에 종속되게 되고, viewmodel을 다른 view에서 재사용할 수 없기 때문이다. 또한 view는 model 대신 viewmodel을 통해서만 data에 접근 가능해야 한다. viewmodel이 모르는 data가 view에 존재한다면, 결국 접근을 위해 view를 참조해야 하기 때문이다.  이런 식으로 MVVM의 제약을 잘 이해하고 적용시켜야 데이터의 흐름을 일관성 있게 제어하고 UI와 로직을 완벽히 분리할 수 있게 된다.

추가로, databinding을 사용하면 activity가 viewmodel에 대해 알아야 하는 내용이 훨씬 더 작아지기 때문에, view와 viewmodel간의 의존성을 더욱 낮출 수 있다. (따라서 다음 포스팅은 databinding을 주제로 작성할 예정!)

사용법

정의 

  • Context 정보가 필요하다면 -> ViewModel 대신 AndroidViewModel 클래스 상속
class MainViewModel: ViewModel() {
}

class MainViewModel(application: Application) : AndroidViewModel(application) {
}

선언

ViewModelProviders → Deprecated
by viewModels() 이용

  • Activity-ktx, fragment-ktx 에서 제공 ( dependency 추가 )
dependency{
    implementation "androidx.activity:activity-ktx:1.1.0"
    . . .
}
  • 선언 시 by ViewModels()
    (AndroidViewModel 생성 시에도 applicationContext 넣어줄 필요 없음!)
val mainViewModel: MainViewModel by viewModels()
// or
val mainViewModel by viewModels<MainViewModel>()

정리

MVVM은 디자인 패턴 중 하나로, 반드시 정답은 아니다. 다만 구글에서 안드로이드 개발에 권장하고 있으며 편리한 라이브러리를 많이 제공하고, 또 MVVM 패턴 자체도 여러 장점이 있기 때문에 최근의 트렌드는 MVVM 개발을 따르고 있는 것 같다.

ViewModel은 이 MVVM 패턴의 핵심이 되는 부분이다. 하지만 AAC에서 제공하는 ViewModel을 단순히 사용만 한다고 MVVM의 장점을 그대로 느낄 수는 없을 것이다. MVVM 패턴에서 ViewModel의 역할을 잘 이해하고, view와 model과 관련된 제약을 잘 지키며 개발해서 진정한 MVVM 패턴의 의의를 느껴 보자!

참고

https://charlezz.medium.com/viewmodel이란-무엇인가-viewmodel-초보를-위한-가이드-e1be5dc1ac18
https://woovictory.github.io/2019/05/02/What-is-ViewModel/

profile
여정이 곧 보상

0개의 댓글