! 지난 시간에는 안드로이드 4대 컴포넌트에 대해 공부했고, 이를 바탕으로 이번에는 안드로이드에서 권장 하는 아키 텍처에 대해 공부를 진행했다.
공부는 다음 사이트를 참고 했다. 안드로이드 공식 문서 -앱 아키텍처 가이드
아키텍처에 대해 배우기 앞서서 모바일 앱 사용자 환경을 보고 넘어가야할 필요가 있다.
일반적으로 Android 앱에는 Activity, Fragment, Service, Content Provider, Broadcast Receiver 등등의 앱 컴포넌트가 포함되어있다.
개발자들은 manifest에서 이와 같은 앱 구성요소들을 선언하고, Android OS에서 이 파일들을 사용하여 기기의 전반적인 사용자 환경(모바일 앱 사용자 환경)에 앱을 통합하는 방법을 결정한다.
그래서 Android 앱에서 올바른 모바일 앱 사용자 환경을 위해 사용자가 짧은 시간 안에 여러 앱과 상호작용할 때가 많다는 점을 고려하여, 사용자 중심의 다양한 워크플로 및 작업에 맞게 조정될 수 있도록 해야 한다.
예를 들자면, 우리가 소셜 네트워크 앱에서 사진을 공유하는 상황이라고 생각해보자.
먼저 이 소셜 앱에서 카메라 인텐트를 트리거한다. 그럴 경우 Android OS에서 요청을 처리하기 위해 카메라 앱을 실행한다. 이 시점의 경우 소셜 앱을 사용자가 나간 상황이지만 계속 해서 끊김없이 연결된다.
후에 카메라 앱은 다른 인텐트를 트리거하여 앨범과 같은 또 다른 앱을 실행하여 사용자가 소셜 앱으로 앨범에 있는 사진을 공유할 수 있도록 한다.
이렇게 사진을 공유하는 과정에서 언제든지 전화 및 알림 등에 의해서 사용 환경 이 중단될 수 있다. 하지만 사용자의 경우는 앱 사용에 흐름이 끊기지 않고 언제든지 다시 사진 공유 프로세스로 돌아가서 작업을 이어가기를 기대한다.
우리가 보통 앱을 사용할 때 위와 같은 예시처럼 사용하는 경우가 일반적이기 때문에, 우리는 앱에서 이러한 흐름을 올바르게 처리할 필요가 있다.
추가로 우리가 사용하는 핸드폰의 리소스는 제한되어 있기 때문에, os에서 새로운 앱을 위한 공간을 확보하도록 언제든지 일부 앱 프로세스를 종료해야 할 필요가 있다.
결론적으로 이러한 환경 조건을 고려해 봤을 때 앱 구성요소는 개별적이고 비순차적으로 실행될 수 있고, os나 사용자가 언제든지 앱 구성요소를 제거할 수 있다.
하지만 개발자들이 이러한 이벤트를 직접 제어할 수 는 없기 떄문에 앱 구성요소에 앱 데이터나 상태를 저장해서는 안되며 앱 구성요소가 서로 종속되면 안된다
위의 내용을 통해서 왜 앱 구성요소에 데이터 및 상태를 저장해서는 안되는지를 알 수 있었다
그렇다면 앱을 어떻게 설계해야 하는 걸까? 다음 두 가지 원칙을 통해 알아보도록 하자
가장 중요한 원칙으로 보통 개발을 처음 시작하면서 하는 실수 중에 하나가 Activity나 Fragment에 모든 코드를 작성한다.
나도 처음 시작하고 간단한 To-do 앱을 만들 때에 한 Activity에 모든 것을 다 때려박곤 했다. 이번 앱잼때에도 다 때려박긴 했다. 반성...😂
Activity나 Fragment같은 UI 기반의 클래스는 UI 및 운영체제 상호작용을 처리하는 로직만 포함해야 한다. 이런 방식으로 해야 수명 주기 관련한 문제들을 피할 수가 있게 된다.
Activity와 Fragment의 경우 Android Os와 앱 사이의 계약을 나타내도록 이어주는 클래스 이며,
위에서 말한 사용자 워크플로우를 수명주기 조절을 통해 끊기지 않고 조절해 주는 역할을 한다는 것이다.
즉, Activity나 Fragment에서는 수명 주기에 따른 상황에 대처할 수 있는 코드만이 있는 것이 좋다.
모델은 앱의 데이터 처리를 담당하는 구성 요소로, 앱의 View 객체 및 앱 구성요소와 독립되어 있어서 앱의 수명 주기 및 관련 문제의 영향을 받지 않는다.
즉 데이터 관리를 모델 클래스에서 이루어지도록 하면 Android Os에서 리소스를 확보하기 위해 앱을 제거해도 사용자 데이터가 삭제되지 않고,
네트워크 연결이 취약하거나 연결되어 있지 않아도 앱이 계속 작동하는 장점을 가질 수 있다.
지금까지 권장 앱 아키텍처를 배우기 위해 사용 이유와 원칙에 대해서 공부해왔다.
이제 진짜 권장하는 앱 아키텍처에 대해 알아볼 차례이다.
우선 사용자 프로필을 표시하는 UI를 제작한다고 가정해보자. 추가로 사용자 프로필 관련한 정보는 REST API를 사용해 서버를 통해 가져온다.
지금 밑에 보이는 다이어그램이 권장 앱 아키텍처의 전체적인 모습이다.
그림을 보면 Activity/Fragment, ViewModel, Repository, Model, Remote Data Source가 있다.
게다가 각 구성요소는 한 수준 아래의 구성요소에만 종속되어 있음을 볼 수 있는데 예를 들면, Activity/Fragment의 경우 ViewModel에만 종속되어 있다.
하지만 Respository의 경우 Model과 Remote Data Source 두 가지에 종속되는데 Repository는 여러 개의 다른 클래스에 종속되는 유일한 클래스이기 때문이다.
위의 설계가 어떻게 일관되고 올바른 사용자 환경을 제공하는지 좀더 요목조목 따져보면서 알아보도록 하자!
코드가 아닌 생각으로 만들어 보도록 하겠음!
먼저 UserProfielFragment와 user_profile_layout.xml을 생성한다.
이때 UI를 도출하기 위해 데이터 모델에 다음 두가지의 데이터 요소가 있어야 한다.
사용자 ID : 사용자의 식별자. 프래그 먼트 인수를 사용하여 정보를 프래그먼트에 전달하는 것이 좋다. 그 이유는 Andorid OS에서 프로세스를 제거해도 이 정보가 유지되므로, 앱을 다시 실행할 때 ID를 사용할 수 있다.
사용자 객체 : 사용자에 관한 세부정보를 보유하는 데이터 클래스
ViewModel 아키텍처 구성요소에 기반한 UserProfileViewModel을 사용하여 이 정보를 유지한다.
예를 들면, ViewModel은 데이터를 로드하기 위해 ViewModel의 하위인 Repository를 호출하고 사용자 요청을 전달하여 데이터를 수정할 수 있다.
추가로 ViewModel은 UI 구성요소에 관해 알지 못하기 때문에 Activity 및 Fragment의 수명 주기 변동에 영향을 받지 않는다.
즉, UserProfileViewModel의 역할은 UserProfileFragment에서 볼 수 있도록 데이터를 준비하고 UI에 반응하는 클래스이다.
위의 다이어그램을 봤을 때 Activity/Fragment에 ViewModel이 하위로 나와 있는 것을 볼 수 있었다.
그러므로 우리는 UserProfileViewModel을 UserProfileFragment에 연결을 해야한다.
이때 사용하는 것이 LiveData이다.
이 LiveData를 통해 변경사항 등을 즉각적으로 모니터링 할 수 있다.
추가로 UI 클래스와 같은 앱 구성요소으이 수명 주기 상태를 고려하고, 과도한 메모리 소비를 방지하기 위한 정리 로직을 포함한다.
이 코드에서 LiveData는 사용자 ID와 사용자 객체를 담고 있다.
이 예제에서는 백앤드로 REST API를 제공한다고 가정한다. 그리고 Retrifit2 라이브러리를 사용하여 백엔드에 액세스 한다.
ViewModel 구현을 위해 서버를 직접 호출하여 데이터를 가져오고 이 데이터를 LiveData에 할당하는 방법이 있다.
하지만 이 설계 방법의 경우, 앱이 커지면서 유지관리가 어려워질 수 있고 ViewModel 클래스에 너무 많은 책임을 부여하면서 위에서 정리했던 아키텍처 원칙 중 가장 중요한 관심사 분리원칙을 위반하게 된다.
또한 ViewModel의 경우에는 Activity와 Fragment 수명 주기와 연관되어 있기 때문에, UI 클래스의 수명 주기가 끝나면 서버 데이터가 손실된다.
따라서 ViewModel에서 데이터를 가져오는 프로세스를 대신하여 Repository 클래스를 활용한다.
UserRepository라는 파일을 생성하고 여기에 서버 통신과 관련한 로직을 작성해준다.
Repository 클래스에서 서버와의 통신을 통해 얻어온 데이터를 ViewModel 클래스에 넘겨준다.
Repository를 통해 데이터를 Viewmodel에 넘겨 주면, UI 기반의 클래스(Activity, Framgent)에서는 위에서 나온 LiveData를 관찰하여 데이터가 바뀌었다는 상황을 알아차린다. 그 뒤 UI 객체에 업데이트 작업이 발생하게 된다.
현재까지 Repository에서 Remote Data Source로의 로직을 예시로 들어서 정리했다. 안드로이드 공식 문서에서는 데이터의 지속성을 위해 Room 사용법 까지 알려주기 때문에 이에 대한 공부도 계속해서 할 예정이다.
적절한 사용자 환경 조성
아키텍처 원칙
권장 앱 아키텍처 : Activity/Fragment, ViewModel, Repository, LiveData 등등 잘 기억하기!!
추가로 이 지식을 바탕으로 MVVM패턴 공부해보기~