MVVM 패턴
Last updated
Last updated
기존 MVC / MVP 디자인 패턴의 단점들을 극복하는 오늘날 가장 많이 사용되고 있는 디자인 패턴 중 하나이다.
Model-View-ViewModel (MVVM) 은 어플리케이션의 UI와 비즈니스 로직을 분리하여 유지보수에 용이하며, 테스트를 쉽게 할 수 있는 장점이 있다.
View
UI에 관련된 작업만을 구현하며, ViewModel 에 사용자의 작업을 알린다. ViewModel 이 비즈니스 로직에 대한 결과값을 반환하지 않으며, ViewModel을 관찰하며 상태에 따른 UI 처리를 한다.
ViewModel
수명 주기를 고려하여 UI 관련 데이터를 저장하고 관리한다. Model 과 View 사이의 연결 고리 역할을 한다.
Model
ViewModel 이 요청한 데이터를 저장하거나 Room, SQLite 등 로컬DB 을 사용하거나 네트워크 통신을 통한 데이터를 가져오는 역할을 한다.
시스템에서 UI 컨트롤러를 제거하거나 다시 만드는 경우, 컨트롤러에 저장된 모든 UI 관련 데이터가 삭제된다.
디바이스 화면 회전하는 경우 위와 같이 컨트롤러를 제거한 후 새로 생성을 한다. 단순한 데이터를 복원하기 위해서는 onSaveInstanceState()
메서드를 사용하여 onCreate()
호출 시 데이터를 복원할 수 있다.
하지만 이 방법은 소량의 데이터에만 적합하다.
ViewModel
객체는 이러한 상황에서 자동으로 보관되어 액티비티 / 프래그먼트 인스턴스에서 즉시 사용할 수 있다.
위에 코드와 같이 뷰모델 클래스는 Jetpack에서 제공하는 ViewModel
을 상속하여 만들 수 있고,
액티비티나 프래그먼트에서 객체생성하여 사용할 수있다.
ViewModel 은 LifecycleOwners 의 특정 인스턴스화보다 오래 지속되도록 설계되어있다. 뷰모델 객체에는 View, Activity, Fragment 객체나 Context를 참조하면 안된다. 시스템 서비스를 찾는데 ApplicationContext 가 필요한 경우에는 AndroidViewModel 클래스를 확장하여 사용할 수 있다. ViewModel 객체의 범위는 ViewModel 을 가져올 때 ViewModelProvider 에 전달되는 Lifecycle 로 지정된다. 범위로 지정된 Lifecycle 이 완전히 끝날때 까지 메모리에 남아있다. 위 코드에 액티비티에서 뷰모델을 초기화할 때 ktx 라이브러리를 사용하는 경우 객체의 범위를 쉽게 지정할 수 있다.
하나의 액티비티에서 둘 이상의 프래그먼트를 사용할 때 각각의 뷰모델을 작성하게 되면 둘 이상의 프래그먼트에서의 결합이 쉽게 처리될 수 없는 부분이기에 공유되는 뷰모델을 사용해야 한다.
위 코드와 같이 사용하면 액티비티에 연결된 뷰모델 객체를 공용으로 프래그먼트에서 사용할 수 있다.
방법1 에서처럼 activity-ktx 와 같이 fragment-ktx 라이브러리를 사용하여 간단하게 인스턴스화 할 수 있고,
방법2 는 기존 액티비티에서 뷰모델을 연결한거 같이 사용하면 된다. 여기서는 ViewModelProvider에 Lifecycle을 this
로 설정하게되면 자기 자신(프래그먼트)에 라이플사이클을 따라가기 때문에 연결된 액티비티 라이플사이클을연결시켜줘야 한다.