MVVM 패턴 | Today I Learned

hoya·2022년 5월 1일
0

Today I Learned

목록 보기
6/11
post-thumbnail

😊 읽기 전, 숙지하고 있으면 좋은 포스팅들


🧑🏻‍🏫 MVVM 패턴의 역사

MVVM의 개념적 원리는 마틴 파울러(Martin Fowler)가 2004년에 발표한 프레젠테이션 모델(PM) 을 통해 처음 언급되었다. 프레젠테이션 모델은 뷰의 상태와 행동을 담는 공간인데, 이 개념이 당시에는 꽤 이목을 끌었던 소재였다.

이윽고 2005년에 WPF와 실버라이트의 설계자인 존 고스맨(John Gossman)이 데이터바인딩을 활용해 UI , 비즈니스 로직, 프레젠테이션 로직의 분리를 최우선 목적으로 삼는 MVVM 패턴을 블로그에 공개하였다. 여기서 PM의 개념과 상당히 유사한, 뷰의 상태와 행동을 담는 뷰모델(ViewModel)을 정의하였다.

MVVM 패턴은 초기엔 WPF에서 주로 사용되어 인지도가 낮았으나 시간이 흐르며 iOS, 안드로이드와 같은 모바일 환경에서 앱 구조가 복잡해짐에 따라 주요 디자인 패턴으로 채택하며 이용률이 꾸준히 올라 가고 있는 추세이다.


📚 MVVM 패턴의 개념

MVVM 패턴에는 Model, View, ViewModel 이라는 세 가지 핵심 컴포넌트가 있고, 각각의 컴포넌트 특성에 대해 알아보기에 앞서 컴포넌트 간의 관계를 먼저 파악할 필요가 있다.

View -> ViewModel -> Model

  • ViewViewModel을 알지만, ViewModelView를 알지 못한다.
  • ViewModelModel을 알지만, ModelViewModel을 알지 못한다.

이런 구조를 통해 ViewModelModelView로부터 독립적인 형태가 완성되고, UI로부터 비즈니스 로직과 프레젠테이션 로직을 분리할 수 있게 되어 MVVM의 근본적 목적을 달성할 수 있게 된다.

이 관계를 잘 기억하면서 각 컴포넌트의 특성을 알아보자.

View

View는 유저가 보는 화면의 구조, 레이아웃을 나타낸다.

  • View는 자신의 레이아웃에 맞는 ViewModel을 참조할 수 있게 되며 보통 ViewViewModel의 관계는 N:1로 형성된다.
  • View에 표현할 데이터가 필요할 때는 주로 데이터바인딩(Data Binding)을 통해 ViewModel에서 가져온다.

이 과정에서 ViewViewModel을 알지만 ViewModelView를 알 수 없는 관계가 형성되고, 이로 인해 View가 DB에 직접 접근하는 것이 아니라 UI 업데이트에만 집중하게 되어 데이터 변화에 능동적으로 대응할 수 있게 된다. 이 부분이 우리가 흔히 아는 MVC 패턴과 가장 큰 차이라고 할 수 있다.

  • 🤔 데이터바인딩?
    데이터바인딩이란 Model과 UI의 데이터 소스를 일치시키는 기법을 의미하는데, MVVM에서는 ViewModel에서 데이터 변경이 일어나면 View의 화면도 이에 맞춰 변경이 일어나는 것이라고 보면 이해가 쉽다.

ViewModel

ViewModelView가 사용할 메소드와 필드를 구현하고, 데이터를 Model에 요청하는 역할을 수행한다. 이 과정에서 상태 변화를 감지하면 이를 View에게 알리고, 그 변화에 맞춰 화면을 변화시킬 것인지는 View에서 결정한다. 대체적으로 MVC의 Controller와 유사한 역할을 맡고 있으나 역시 가장 큰 차이점은 View에 대해 전혀 모르고 있다는 점이다.

Model

데이터에 대해 접근하고 검증하는 로직, 즉 비즈니스 로직이 포함되어 있다. MVVM에서는 ViewModel이 요청한 데이터를 반환하는 역할을 주로 수행하고 있으며 MVC의 Model과 거의 유사하다.

MVVM 사용 시나리오

  1. 사용자가 View를 통해 요구 사항을 요청한다.
  2. ViewModel에게 요청을 전달한다.
  3. ViewModel은 요청에 따라 필요 데이터를 Model에게 요청한다.
  4. Model은 요청에 맞춰 데이터를 응답한다.
  5. ViewModel이 응답받은 데이터를 가져오고 이를 가공하여 저장한다.
  6. View는 데이터바인딩을 통해 ViewModel의 데이터를 즉시 전달받고 이를 화면에 나타낸다.

🖐 MVVM의 장점과 단점

장점

  • 로직들이 분리되어 있기 때문에 유닛 테스트가 간편해진다.
  • 각 컴포넌트를 독립적으로 개발할 수 있다. (디자이너로부터 디자인을 받지 못한 시점에서도 다른 컴포넌트를 개발할 수 있음)
  • 개발 중 일어나는 많은 변화에 대응하기 편하다. (왜? 로직을 꼼꼼하게 분리해놓았으니까!)

단점

  • 처음부터 거대하고 복잡한 앱을 유지보수하기 위해 고안된 디자인 패턴이라 설계가 어렵다.
  • 데이터바인딩 기법을 통해 View의 변화를 나타내고, 이 과정에서 간단한 로직을 만들 때도 많은 코드와 클래스의 작성을 요구로 한다.

📱 안드로이드에서의 MVVM

안드로이드 개발을 진행할 때 MVC 패턴을 따라가게 되면 보통 액티비티가 View, Controller의 역할을 모두 수행하기 때문에 상당한 양의 코드로 구성된 경우가 많다. 동작에 있어 문제가 발생하지는 않지만 동작이 늘어날 수록 액티비티가 점점 무거워지고 이 후 수정이나 유지보수에 어려움을 겪는 경우가 많아진다. 이를 보통 스파게티 코드라고 하는데, 안드로이드 측에서는 개발자들의 이런 어려움을 조금이나마 해소시키기 위해 MVVM 패턴 구현에 용이한 AAC(Android Architecture Component)를 제공하고 있다.

AAC

MVVM에 맞춰 역할을 나누면 위에서부터 View - ViewModel - Repository - Model 순으로 흐름 이 진행된다. 자료 속에 있는 구성 요소를 하나씩 살펴보도록 한다.

View

UI를 담당하는 액티비티나 프래그먼트를 의미하며 화면에 무엇을 그릴지 결정하고 사용자와 상호 작용한다. 데이터의 변화를 감지하기 위해 Observer를 가지고 있다.

ViewModel

UI를 위한 데이터를 가지고 있으며 View와 분리되어 있기 때문에 화면 변화에도 데이터가 사라지지 않는다. 주의할 점으로, 위의 ViewModel 부분을 읽었다면 알겠지만 AAC ViewModel은 MVVM의 ViewModel과 비교했을 때 개념 자체가 다르다.

LiveData

위에서 이야기한 데이터바인딩을 구현하기 위해 사용되는 핵심적인 구성 요소이다. View에서 ViewModelLiveData를 관찰하게 되면 데이터가 변경될 때 자동적으로 View에게 변경 사항을 알려준다. 액티비티 및 프래그먼트의 생명주기를 인지하고 있으므로 액티비티가 유저의 화면에 활성화되고 있을 때만 데이터의 변경 사항을 View에게 알려 메모리 누수를 방지한다.

Repository

ViewModel과 데이터를 주고받기 위해 데이터 API를 포함하고 있는 클래스이다. 실제 앱에 필요한 데이터를 가져오는 역할을 수행하며 이로 인해 ViewModelModel에 직접적으로 접근하지 않게 되고, 전체적으로 앱 구조의 결합도가 느슨해지게 된다.


🤗 실제 적용

서울열린데이터광장의 오픈 API를 이용하여 실제 적용 사례를 살펴볼 것이며, 위의 자료와 동일 한 과정으로 진행된다. 적용 후 화면에 보여질 것은 서울 지하철역 리스트이다.

MainActivity(View)

자료에서 보는 것과 같이 액티비티에서 핵심적인 부분은 데이터 변화를 감지하기 위해 옵저빙을 하고 있다는 점이다. ViewModel에서 데이터 변화가 일어나면 이에 맞게 UI를 변경한다.

MainViewModel

위의 자료와 같이 ViewModel에서는 직접 데이터에 접근하지 않고 Repository를 이용해 데이터를 받아온다. 그리고 이를 LiveData로 설정하여 데이터에 변화가 생기면 이를 지켜보고 있는 구독자, 즉 View에게 알림이 가도록 설정한다.

StationRepository

실제 데이터에 접근하여 필요한 데이터를 요청하고 받아오는 임무를 수행한다. 전체적인 결합도를 낮춰 유지보수 비용을 완화하기 위해 사용한다.

Model

비즈니스 로직을 처리하고 이에 따른 결과 데이터를 저장하는 공간이다.

결과


✍️ 결론

MVVM 패턴은 위의 적용 예시와 같이 ViewModel 혹은 Repository 같이 낯선 클래스를 새롭게 생성해야 하기 때문에 처음 접하는 사람들에겐 어렵고 복잡하게 보일 수 있다. 또한 개념을 이해한 사람도 기존 MVC 패턴에서 MVVM 패턴으로 마이그레이션을 진행하려 하면 비용이 상당히 많이 소비될 것이다.

그럼에도 불구하고, MVVM 패턴 적용으로 인해 코드 재사용성이 상당히 올라가며 프로젝트 구조가 깔끔해지는 것을 피부로 느낄 수 있었고, 이 과정에서 모바일 시장에서 대부분의 디자인 패턴이 MVVM으로 구성되어 있는 이유를 확실히 알 수 있었다. 물론 모든 상황에 MVVM을 적용하는 것은 옳지 않으나, MVVM의 철학을 이해하고 실제 적용해야 하는 프로젝트가 무엇인지 생각하는 과정을 적절하게 거친다면 MVVM을 보다 더 잘 활용할 수 있게 될 것이다.


참고 및 출처

MVVM & 안드로이드 아키텍쳐 컴포넌트 시작하기
[Prism 4.1] MVVM 패턴 구현하기
MVVM 패턴이란? UIKit의 MVC와의 비교
깔쌈하게 MVVM 패턴과 AAC 알아보기

profile
즐겁게 하자 🤭

1개의 댓글

comment-user-thumbnail
2022년 5월 2일

아하 감사합니다!

답글 달기