필자는 최근 아무 생각 없이 코드 짜서 유지보수성 포기하기 대회에서 최우수상을 수상하는 영예를 안았다.
취업 준비를 위해 포트폴리오를 준비하고 있었는데, 나도 모르게 앱 크래시가 발생하기 시작했다. git 버전 관리도 제대로 모르고 해왔던 터라 문제 해결이 쉽지 않았다. 포트폴리오는 반포기 상태에 이르렀고, 기본기 공부를 시작하게 되었다. 그러던 중, Android Architecture(Design) Pattern에 대해 알게 되었다.
Architecture(Design) Pattern?
아키텍처 패턴? 구조 패턴 정도로 해석이 되는데, ECB 구조 패턴을 배우던 강의시간에 들었던 용어인 것으로 기억난다.
반대로 해석하면, 아키텍처 패턴을 적용하지 않고 앱 개발을 하면 문제가 발생했다는 것이다. 꽤나 일리 있는 말이다. 정형화된 구조나 기준 없이 앱 개발을 진행하다 보면, 우리의 코드는
가 돼있을 것이다. 자, 아키텍처 패턴에 대한 키워드를 듣고도 무시하고 코드를 짤텐가? 선택은 우리의 몫이다. Yes라고 하면 필자처럼 될 확률이 높다. 지금까지의 앱 개발자들에게 "어느정도 증명된" 안드로이드 설계구조 방식이라고 생각하면 될 것 같다.
이 해답은 하나가 아니라 여러 개가 존재한다. 그리고 각 아키텍처 패턴마다 장단점도 존재하기에 이를 잘 알고 있어야 당신의 프로젝트에 적절한 아키텍처 패턴을 적용할 수 있다. 널리 알려진 아키텍처 패턴은 MVC, MVP, MVVM이 있다. 한 번 알아보자!
MV/C/P/VM
앞의 MV가 겹치는데, 이는 우연이 아니다. M은 Model을 의미하고, V는 View를 의미한다. 다만 각 아키텍처 패턴에서 Model과 View의 역할이 조금씩 달라질 수 있다. 기본적으로
구조적으로 Model, View, 각 아키텍처 패턴의 C, P, VM이 서로 어떻게 상호작용하는지를 중점으로 글을 읽으면 된다.
간략한 역할 설명
- Model : 데이터
- View : 순수 xml
- Controller : 액티비티
안드로이드 아키텍처를 접해본 적이 없는 이들이라면, MVC와 가장 유사한 형태로 개발을 해왔을 것이다.
MVC
Activity.kt 파일에 앱 동작 코드를 다 써버렸다!
간략한 역할 설명
- Model : 데이터
- View : xml + 액티비티 + 뷰 인터페이스
- Presenter : Model과 View를 이어주는 인터페이스
MVC에서 View와 Model의 결합도가 높다는 단점을 보완하기 위해 MVP가 등장했다.
MVP
MVC에서 View와 Model의 의존성을 제거한 디자인 패턴이다.View 와 Model이 Presenter를 통해서만 동작할 수 있도록 하자!
간략한 역할 설명
- Model : 데이터
- View : xml + 액티비티
- ViewModel : Model과 View를 이어주는 인터페이스
MVC에서 View와 Model의 결합도가 높다는 단점을 보완하기 위해 MVP가 등장했다.
MVP에서도 Presenter의 코드량이 비대해질 수 있다는 단점이 있기에 MVVM이 등장했다.
MVVM
안드로이드 데이터 바인딩을 사용하는 디자인 패턴이다.View는 ViewModel이 들고 있는 데이터를 관찰하여 UI 업데이트한다.
Model은 ViewModel의 요청에 따른 데이터를 가져온다.
View는 ViewModel 데이터 관찰 및 UI 업데이트
- 결국 View 가 필요로 하는 데이터는 ViewModel 이 쥐고 있고, View 는 그것을 필요로 하기 때문에 ViewModel 이 쥐고 있는 데이터를 관찰 (Observing) 한다.
- 때문에 MVC 패턴과 다르게, View 가 DB 에 직접 접근하는 것이 아닌 UI 업데이트에만 집중한다. 또한 관찰하고 있는 만큼 데이터 변화에 더욱 능동적으로 움직이게 된다.
- View 가 ViewModel 의 Data 를 관찰하고 있으므로 UI 업데이트가 간편
- ViewModel 이 데이터를 홀드하고 있으므로 Memory Leak 발생 가능성 배제
- View 가 직접 Model 에 접근하지 않아 Activity / Fragment 라이프 사이클에 의존하지 않기 때문
- 기능별 모듈화가 잘 되어 유지 보수에 용이 (e.g. ViewModel 재사용 및 DB 교체 등의 작업이 편리함)
AAC
- MVVM 패턴을 간편하게 적용해볼 수 있게끔 구글에서 AAC 라는 것을 제공한다.
- AAC는 ViewModel을 쉽게 사용할 수 있도록 해준다.
ViewModel은 데이터를 가지고 있음
- 앞서 설명한대로, 화면 변화 시에도 변하지 않는 (사라지지 않는) 데이터를 가지고 있다.
- Live Data
- View 가 ViewModel 을 관찰할 때, 그 관찰 대상이 되는 데이터 홀더 클래스이다.
- Live Data 는 Activity 및 Fragment 의 Life Cycle 을 인지하지 못하므로, “화면이 활성화 되어 있을 때만 동작하여” 메모리 릭을 줄여준다.
- Repository
- ViewModel과 데이터를 주고받기 위해, 데이터 API 를 포함하는 클래스다.
- 사용자 동작에 따라 필요한 데이터나 외부 백엔드 서버 등에서 데이터를 가져와서 ViewModel로 반환해준다.
- Repository의 존재 덕분에 ViewModel이 데이터를 관리할 필요가 없게 된다.
- RoomDatabase
- Room 은 SQLite 를 사용함에 있어 별도의 Query문 작성없이 간편하게 Insert, Delete 등의 동작을 할 수 있게끔 도와주는 ORM 라이브러리이다.
- 공식 문서에 따르면 Realm 같은 라이브러리를 사용해도 상관이 없다고 한다.
MVC에 비해 MVP와 MVVM은 앱을 보다 모듈화하고 구성 요소를 단일 용도로 분해한다는 점에서 발전된 모습이지만, 이 구조 때문에 앱이 더 복잡해질 수 있다. 한 두 개의 화면으로만 구성된 간단한 앱이라면 MVC만으로도 충분하다. 한편 데이터 바인딩을 사용하는 MVVM은 보다 반응이 빠른 프로그래밍 모델을 따르고 적은 코드를 사용한다는 점에서 매력적이다.
그렇다면 어떤 패턴이 여러분에게 적합할까? MVP와 MVVM 중 하나를 고른다면 개인 취향에 따른 많은 결정 사항이 있겠지만, 장단점을 파악하기 위해서는 실용적인 관점에서 보는 것이 좋다.
MVVM도 이점을 살리지 못하고 잘 활용하지 못하면 괜히 구조만 복잡한 프로젝트가 될 것이다. 따라서 기능 각각을 어떻게 분류하여 어떤 컴포넌트에 포함해야 제일 효율적일지 생각하는 것이 과제가 될 것이다.
MVVM은 제대로 쓰면 좋지만 엉성하게 쓸꺼면 쓰지말라. 라고 얘기하네요.
AAC 가 있다고 한들, 막상 사용하려니 이론은 이해가 되는데 구현을 어떻게 해야할 지 감이 안 잡힐 수 있다. 예제를 보고 따라해보면서 구현 방식을 이해하고 익숙해지는 과정이 중요하다.