본문 바로가기
Mobile App

[안드로이드] MVVM 패턴과 안드로이드 MVVM 패턴

by Jman 2023. 2. 11.

마이크로소프트 MVVM 패턴 VS Google AAC ViewModel (android mvvm pattern)

처음에 굉장히 혼잡했다.. AAC ViewModel 개념을 볼 때 이게 MVVM 과 다르다는 말을 하는데, 무엇이 다르다는 지 처음에는 많이 헷갈렸다. 그래서 오늘 MVVM을 톺아보려 한다.

이번 블로그에서는 Google AAC ViewModel 과 Microsoft 아키텍트 존 구스먼이 발표한 MVVM 의 ViewModel 차이를 가지고 설명할 것 같다.

 

MVVM 패턴은 마틴 파울러의 MVP(프레젠테이션 모델) 디자인 패턴을 변형하여 만든 것이고, 2005년에 마이크로소프트 아키텍트인 '존 구스먼' 이 처음으로 공개해 세상에 알려졌다.

 

구글은 '존 구스먼'이 발표한 MVVM 패턴과 흡사하게 안드로이드에 맞는 MVVM 패턴을 만들고자 AAC ViewModel 을 발표했다고 생각하면 된다. 하필.. ViewModel 이라는 말을 같은 단어로 사용하게 되면서 많은 개발자들이 혼동을 겪은 것 같다.

 

구글은 점차 '존 구스먼' 이 발표한 MVVM 패턴을 비슷하게 적용할 계획을 세웠던 것 같다.

그 이유는, MVVM 패턴은 네 가지 중요한 구성(Model, View, ViewModel, Binder) 있는데 위 네 가지가 성립해야만이 처음으로 공개한 존 구스먼의 MVVM 패턴이라고 할 수 있다.

💡Binder? 바인더는 뷰 모델과 뷰의 동기화를 위해 상용구 로직을 작성해야 하는 의무에서 개발자를 해방시켜준다.
마이크로소프트 스택을 사용하지 않고 구현한다면, '선언적인 데이터 바인딩 기술'이 있어야 이 패턴을 만들 수 있으며, 바인더가 없다면, 그 대신 일반적인 MVP 나 MVC 를 사용해야 할 것이고 더 많은 상용구 코드를 작성하게(아니면 이를 다른 도구로 생성하게) 될 것이다.

 

그런데 구글은 2017년 ViewModel 을 발표하기 전에, 먼저 2015년에 MVVM 패턴에 Binder 와 비슷한 개념인 Databinding 을 발표했다. 그 이후에 ViewModel 을 발표하고서, AAC ViewModel 이라는 개념을 널리 알렸다.

 

우리가 생각하는 흔한 착각?

View 에서 ViewModel 의존성을 갖고 Obseve 하는 코드가 존재한다면, MVVM 패턴을 적용했다라는 착각

위 글은 정말 착각이다.

Google 에서 발표한 AAC ViewModel의 ViewModel 은 화면 회전과 같은 상태 변화가 일어나는 환경에서 UI 와 관련된 데이터를 라이프 사이클에서 관리하고 유지하는 클래스라고 설명되어있고, 절대 MVVM 패턴의 ViewModel 이라고 거론한 적은 없다.

 

즉, 우리가 착각하는 걸 다시 이야기하면 우린 MVVM 패턴을 적용했다라고 생각하지말고, ViewModel 을 적용했다라고 생각을 해야한다.

 

마이크로소프트 MVVM 패턴의 ViewModel

: 뷰와 모델 사이에서 데이터를 관리하고 바인딩을하기 위한 목적의 클래스다. 값 변경 이벤트가 발생 했을 때, 그 상태 변화를 뷰에 알리게 된다.

구글 AAC ViewModel 의 ViewModel

: 수명 주기를 고려하여 UI 관련 데이터를 저장하고 관리하도록 설계된 클래스

 

그러면, 우린 안드로이드에서 MVVM 패턴을 적용했다라고 하려면 어떻게 해야할까?

MVVM + Databinding 을 사용해야 MVVM 패턴을 적용했다 라고 말할 수 있다.

그래야 존 구스먼이 발표한 내용에서 언급한 Binder 라는 개념이 포함 돼, 진정한 MVVM 패턴을 도입했다라는 말을 할 수있다.

 

MVVM

사용자 인터페이스(View)의 개발을 비즈니스 로직 또는 모델로부터 분리시켜 뷰가 어느 특정한 컴포넌트에 종속되지 않도록 해준다.

MVVM 특징

MVVM 의 핵심은 view 와 viewModel 연결을 최소화 한다는 점에 있다.

ViewModel 에서는 View 를 모른다. 단순히 View 가 ViewModel 을 알고 있다

view와 viewMdoel 은 다대 다 관계가 가능하다.

따라서 하나의 View는 1개 이상의 ViewModel 과 연결될 수 있고, 또한 1개의 ViewModel 도 1개 이상의 View 와 연결될 수 있다.

 

Binder

MVVM 에는 Model, View, ViewModel 이외에도 Binder 라는 핵심 구성요소가 있다.

안드로이드에서는 이 부분을 Databinding 을 통해 지원한다.

 

MVVM 장점

- 바인딩으로 통해, 코드양이 감소한다.

- 뷰 의존성이 제거가 돼서, 테스트가 굉장히 편해졌다.

💡 어떻게 편해졌는데? 프레젠터를 테스트를 하기 위해선, 뷰를 모킹하여, 해당 뷰에 함수가 제대로 호출 됐는지 테스트를 했지만?

뷰모델에선 뷰모델 하나만 잘하면 된다.

 

의존성

  • app 모듈에 코드를 자동으로 생성하는 툴인 kapt 활성화
  • app 모듈에 fragment-ktx 의존성 추가
  • app 모듈에서 데이터바인딩 활성화

 

데이터바인딩 변수 참조

  • 단방향일 경우에는 @{...}
  • 양방향일 경우에는 @={...}
  • 괄호 안에서는 자바처럼 코딩 가능
    • android:visibility="@{age > 13 ? View.GOME : View.VISIBLE}"

 

데이터 바인딩 클래스 사용

kapt 를 통해 자동으로 생성된 데이터바인딩 클래스 사용

 

방법1

private lateinit var binding: ActivityMainBinding

orverride fun onCreate(savedInstanceState: Bundle?) {}
	val binding = ActivityMainBinding.inflate(layourInflater)
	setContentView(binding.root)
}

방법2

private lateinit var binding: ActivityMainBinding

orverride fun onCreate(savedInstanceState: Bundle?) {}
	binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
}

=> 이렇게 사용하는 이유는? 특정 Activity 바인딩 클래스 의존하고 싶지 않는 경우, 위와같이 사용할 수 있다.

보통 BaseActivity 에서 데이터바인딩 유틸을 쓰게 될경우, 특정 액티비티에 바인딩된 클래스가 없더라도, 레이아웃 파일 리소스 아이디만 받아서 베이스 클래스를 생성할 수 있다.