-
Android) MVVM 패턴 깊게 알아보기Android 2021. 2. 10. 17:40
안드로이드 개발에 있어 대부분 디자인 패턴을 적용하여 개발을 합니다. 대표적으로 MVC, MVP, MVVM, MVI 등이 있습니다.
저는 주로 MVVM 패턴을 적용하여 개발하고 있습니다.
MVVM 패턴의 뷰 모델은 모델을 알지만 뷰를 알지 못하고 뷰는 모델을 모르지만 뷰 모델을 알 수 있는 특징에서 오는 서로 의존성이 없다는 장점과 AAC(Android Architecure Component)를 적용하기에 최적화 된 패턴이란 이유로 선택하여 쭉 사용해오고 있습니다.
문득 요즘은 내가 사용하는 기술들에 대해 어느 정도로 깊게 알고 사용, 구현하고 있는지에 의구심이 들고 있어
오늘은 해당 MVVM 패턴에 대해 글을 작성해보려고 합니다.
Model
MVVM 패턴의 모델도 MVC, MVP 다른 패턴의 모델과 다르지 않고, 데이터를 가지고 있는 클래스입니다.
데이터라고 함은 메모리, 로컬, 서버 등등 다양한 데이터들이 존재합니다.
이로부터 필요한 데이터를 준비하고 뷰모델에서 데이터를 가져갈 수 있게 해주는 역할입니다.
ViewModel
뷰모델의 이름의 의미는 뷰를 그리는데 필요한 모델이란 의미로 지어졌다고 합니다.
뷰에 연결할 데이터와 명령으로 구성되어 있고 변경 알림을 통해서 뷰에게 상태 변화를 전달합니다.
전달받은 상태변화를 화면에 반영할지는 뷰가 선택하도록 하고 명령은 UI를 통해서 동작하도록 합니다.
뷰 모델은 화면이 그려지는 방법을 모릅니다.
화면은 계속해서 변경될 수 있습니다. 디자이너의 요청에 의해 변경될 수 있고, 혹은 사용자에 의해 버튼, 텍스트뷰, 이미지 뷰 등등 뷰의 위치가 변경될 수 도 있습니다.
여기서 앞서 "뷰모델은 화면이 그려지는 방법을 모른다"는 말이 장점을 발휘합니다. 즉 화면이 변경돼도 뷰 모델은 변경하지 않아도 된다는 의미가 되는 것이죠.
ViewModel은 3가지의 구성요소가 있습니다.
- ViewState(뷰의 상태)
- Value Converter(상태의 조합)
- Command(뷰의 행동)
ViewState
ViewState는 화면이 가지는 본질적인 데이터입니다.
뷰 모델에서 ViewState는 뷰에 의해 입력받기도 하고, ViewState에 따라 뷰를 그려주기도 합니다.
예를 들어 로그인 화면이 있다고 가정해보겠습니다. 이 화면에서 EditText로 구성된 아이디, 비밀번호가 있습니다.
여기서 아이디, 비밀번호가 ViewState가 되는 것이고 사용자로부터 입력받아 뷰 모델에 채워지게 됩니다.
ValueConverter
ValueConverter는 본질적인 데이터들을 가지고 만들어 내는 작업입니다.
다시 로그인 화면을 예로 들어보자면, ViewState인 아이디와 비밀번호가 있겠고 활성화 시킬 수 있는 로그인 버튼이 존재합니다.
이때 로그인 버튼의 활성화 여부가 ValueConverter에 해당이 됩니다.
ViewState인 아이디, 비밀번호가 둘다 공백이 아니어야 하는 조합으로 하나의 불리언 값을 가지게 되고 뷰에 반영되게 됩니다.
코드를 작성할 때 따라서 ViewState로 작성하다가도 ValueConverter으로 표현할 수 있는 형식이 아닌지 고민해봐야 합니다.
ViewState가 적을수록 가독성이 높아지고 모듈화 하기 쉬워지기 때문입니다.
Command
뷰는 사용자에게 정보를 보여주는 역할이기도 하면서, 사용자로부터 이벤트를 받아들이는 역할도 합니다.
따라서 뷰모델은 이러한 이벤트에 대한 처리도 해줄 수 있어야 합니다. 그게 바로 Command입니다.
다시 로그인 화면을 예제로 들자면 로그인 동작이 Command가 될 것입니다.
Command은 항상 ViewState를 활용해 ViewState를 변경하거나 신호를 내보내는 역할을 합니다.
따라서 뷰 모델이 노출한 뷰의 행동은 직접적으로 뷰를 참조하지 않아도 됩니다.
View
뷰는 화면에 표현되는 레이아웃에 대한 창구라고 할 수 있겠죠. 기본적으로 비즈니스 로직(데이터를 묶고 조합하는 작업)을 배제하고 UI와 관련된 로직을 수행합니다.
뷰는 뷰모델을 구독하여 소비하는 객체라고 표현하겠습니다. 뷰는 뷰모델을 옵저빙 즉 관찰하고 있다가 상태변화가 전달되면 화면을 갱신합니다. 뷰는 상황에 따라 상당히 구체적이고 디테일하게 되는 영역이기 때문에, 변화에 민감하여 테스트하기 어렵다는 특징이 있습니다.
따라서 뷰를 멍청하게 구성할 필요가 있습니다. 이 말에 대해서 생각해보겠습니다. 뷰는 데이터를 보여주는 역할임에도, 해당 데이터가 어떻게 생성되었는지 알지 못합니다. 단지 정제된 데이터에 따라 화면에 표시할 뿐이죠.
또한 뷰는 사용자의 이벤트를 뷰모델에게 알려줄 필요가 있습니다. 이는 보통 뷰모델의 Command로 사용자 이벤트를 전달하는 형태로 이루어집니다. 예를 들어 뷰에서 어떤 값의 타입에 따라 다른 행동을 해야 하는 경우가 있습니다. 비즈니스 로직은 뷰모델에 있고 뷰에서 뷰 모델로 이벤트를 전달하게 되어 행동을 취하게 될 것입니다.
Conclusion
결론적으로 MVVM 패턴의 이상적인 모습이라 한다면..
멍청한 View와 정제된 ViewModel, 그리고 안정적인 Model을 구성한 모습이 아닐까 싶네요.
그동안 MVVM 패턴을 사용하면서 기계적으로 코드를 작성해 왔던 것 같은데,
이런 부분에 대해 더 깊게 고민하면서 코드를 작성하게 되면 더 좋은 코드를 작성할 수 있지 않을까 싶습니다.
Reference
반응형'Android' 카테고리의 다른 글
Android) Airbnb에서 만든 MvRx 알아보기 (0) 2021.02.15 Android) RecyclerView를 쉽게 사용하도록 도와주는 Epoxy 알아보기 (3) 2021.02.15 Android) FragmentNavigatiorExtras로 Navigation 간 Shared Element 전환하기 (0) 2021.02.09 Android) 코루틴 Channel과 Flow로 Instant Search 구현하기 (1) 2021.02.08 Android) 코루틴 StateFlow와 SharedFlow 알아보기 및 LiveData와 비교 (0) 2021.02.08