지난 1편에서는 클린아키텍처에 대한 내 생각과 고민점 그리고 리팩토링 하는 과정을 적어봤었다.
이번에는 MVVM
패턴에 대한 내 생각에 대해서 적어보고자 한다.
MVC
는 예전에 아주 많이 사용하였던 전통적인 Android의 디자인 패턴이다.
Model-View-Controller로 구성되어 있으며 각각은 아래와 같은 역할을 한다.
UI Layer
Model
에 저장된 데이터의 시작화XML
이 해당 역할을 수행(컴포즈 이전)Activity/Fragment
가 이 역할을 수행Controller
와 View
를 Activity/Fragment
에서 모두 수행하기도 함이렇게 역할이 나뉘어져있고 모듈식 디자인을 제공함에도 불구하고 코드 레이어는 서로에게 의존한다.
이 패턴에서는 특히 View
와 Controller
는 모두 모델에 의존하게 되고 View
와 Controller
는 모두 비대해져 간다.
즉, 역할이 제대로 분리되지 않는다는 것이다.
MVC
를 대체하기 위해 MVP
, MVVM
, MVI
등의 패턴이 나왔지만 우리는 가장 대중적인 MVVM
을 채택했다.
MVVM
에서 View
는 오롯이 View
의 역할만을 하고(Activity/Fragment) UI 로직은 ViewModel
에서 수행한다.
직접적으로 View
에서 UI를 컨트롤 하지 않고 ViewModel
에서 상태를 핸들링한다.
ViewModel
의 상태는 Layout XML
에서 Observing
하고 데이터가 변경됨에 따라 UI를 Update한다.
그렇기에 Android에서는 Databinding
을 추천하고 있다.
Databinding
사용하지 않는다면 View
에서 Observing
코드가 반복적으로 들어가고 좀 더 UI의 비즈니스 로직이 View
에 종속되어야 하는 문제들이 생겨난다.
그러므로 가히 필수적이라고는 생각이 들긴 하지만 우리팀에서는 사용을 지양하였다.
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/imgFreeShipping"
style="@style/ItemTag"
visible="@{item.property.hasDeliveryFee}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:text="@string/free_delivery"
tools:text="무료배송" />
위에서 MVVM
에 대한 내 생각은 Databinding
이 가히 필수적이라고 생각한다고 했지만 우리는 사용하지 않았다.
이에 대한 우리만의 타당한 이유는 있었고 나도 그에 공감이 갔다.
Databinding
은 분명히 편리한 도구이자 MVVM
에 필요한 요소이다.(MVVM
을 완성본으로 만들어주는 것이랄까...?)
하지만 코드 흐름의 전개를 파악하기가 상당히 난해하고, XML
에서 Code
처리가 되고있는 부분이 좀 더 어렵게 만들어가는 느낌이 들었다. 결국에는 해결할 수 없는 상태변화는 BindingAdapter
를 활용해서 해결해야 한다.
Databinding
을 활용해도 결국에는 View
에서 처리해야 하는 비즈니스 로직이 존재한다..
이를 코드베이스로 레이아웃을 작성하고 재사용성을 높이며 가독성을 좋게하여 해결한 Compose 👍
ViewModel
은 View
와 1:N 관계를 성립하고 재사용 또한 가능하다. 그런데 제대로 된 1:N 관계를 설계하려면 상태 관리에 대해 ViewModel
을 더욱 작게 쪼개야 성립할 수 있을 것 같다.
하지만 개발을 하다보면 ViewModel
이 복잡해지는 경험이 몇번씩 생겼고 팀원들 또한 같은 생각이었다.
사실 뷰모델이 복잡해지는 것은 역할 파악이 제대로 안 되었다고도 볼 수 있다.
뷰모델은 그저 리포지터리에서 데이터를 가져와 뷰상태를 생성하는 것이 역할인데 다른 비즈니스 로직이 들어가거나 그 외의 역할을 하기 때문이다.
이것은 설계된 클린아키텍처를 제대로 활용하지 못하고 있거나 Databinding
을 사용하지 않는 것도 지분을 차지하고 있다고 본다.
이를 위해서는 함께 고민할 시간을 가지며 우리의 컨벤션을 다시 정립해봐야 할 필요가 있다고 생각한다.