앱 아키텍처는 클래스 간에 앱 책임을 할당하는 데 도움이 되는 가이드라인을 제공한다. 앱 아키텍처가 잘 디자인되어 있다면 앱을 확장하고 더 많은 기능을 추가하는데 도움이 된다. 아키텍처는 팀 공동 작업을 간소화시킬 수도 있다.
가장 일반적인 아키텍처 원칙은 관심사 분리와 모델에서 UI 만들기이다.
- 관심사 분리란, 디자인 원칙은 각각 별개의 책임이 있는 여러 함수 클래스로 앱을 나눠야 한다는 원칙이다.
- 모델에서 UI 만들기란, 모델에서 UI를 만들어야한다는 원칙으로, 모델은 앱의 데이터 처리를 담당하고 앱의 UI 요소 및 앱 구성요소와 독립되어 있으므로 앱의 수명 주기 및 관련 문제에 영향을 받지 않는다.
아키텍처 원칙에 대한 더 자세한 내용은 다음을 참고하라.
https://developer.android.com/topic/architecture?hl=ko#common-principles
권장 앱 아키텍처
이전 섹션에서 언급된 일반적인 아키텍처 원칙에 따라 각 앱에는 최소 두 가지 레이어가 포함되어야 한다.
- UI레이어: 화면에 앱 데이터를 표시하지만 데이터와는 무관한 레이어
- 데이터레이어: 앱 데이터를 저장하고, 가져오고, 노출하는 레이어
UI와 데이터 레이어 간의 상호작용을 간소화하고 재사용하기 위해 도메인 레이어라는 것을 추가할 수 있다.
화살표는 클래스 간의 종속성을 나타낸다.
즉, 도메인 레이어는 데이터 레이어에 종속된다.
UI레이어
화면에 애플리케이션 데이터를 표시하는 역할을 지니고 있으며, 버튼 누르기 같은 사용자 상호작용으로 인해 데이터가 변경될 때마다 UI가 변경사항을 반영하여 업데이트되어야 한다.
UI레이어의 구성요소로는 다음과 같은 것이 존재한다.
- UI 요소: 화면에 데이터를 렌더링하는 구성요소로써, 이러한 요소는 Jetpack Compose를 사용하여 빌드한다.
- 상태 홀더: 데이터를 보유하고 UI에 노출하며 앱 로직을 처리하는 구성요소. 상태 홀더의 예시로써 ViewModel이 존재한다.
ViewModel
ViewModel 구성요소는 UI가 사용하는 상태를 보유하고 노출하는 역할을 가진다. UI 상태는 ViewModel에 의해 변환된 애플리케이션 데이터다. ViewModel을 사용하면 앱이 모델에서 UI 만들기 아키텍처 원칙을 따르도록 만들 수 있다.
ViewModel은 Android 프레임워크에서 활동이 소멸되고 다시 생성될 때 폐기되지 않는 앱 관련 데이터를 저장한다. 활동 인스턴스와 달리 ViewModel 객체는 소멸되지 않으며, 앱은 구성 변경 중 자동적으로 ViewModel 객체를 유지하므로 객체가 보유하고 있는 데이터는 재구성 후에 즉시 사용이 가능하다.
앱에 ViewModel을 구현하려면 아키텍처 구성요소 라이브러리에서 가져온 ViewModel 클래스를 확장하고 이 클래스 내에 앱 데이터를 저장한다.
UI 상태
사용자가 보는 항목이 UI라면 UI 상태는 앱에서 사용자가 봐야 한다고 지정하는 항목이다. UI는 UI 상태를 시각적으로 타나내고 UI 상태가 변경되면 변경사항을 즉시 UI에 반영한다.
// Example of UI state definition, do not copy over
data class NewsItemUiState(
val title: String,
val body: String,
val bookmarked: Boolean = false,
...
)
불변성
위 예에서 UI 상태 정의는 변경할 수 없다. 변경할 수 없는 객체는 여러 소스가 한순간에 앱의 상태를 변경하지 않도록 보장하고, 그 덕분에 UI는 상태를 읽고 이에 따라 UI 요소를 업데이트하는 한 가지 역할에만 집중할 수 있게 된다.
따라서 UI 자체가 데이터의 유일한 소스인 경우를 제외하고 UI에서 UI 상태를 직접 수정해선 안된다. 이 원칙을 위반하면 동일한 정보가 여러 정보 소스에서 비롯되어 데이터 불일치와 미세한 버그들이 생기게 된다.
'개발 > AOS' 카테고리의 다른 글
애플리케이션 테스트 02. ViewModel의 단위 테스트 작성 (1) | 2024.05.09 |
---|---|
애플리케이션 테스트 01. 자동테스트란? (0) | 2024.05.09 |
rememberSaveable이란 (0) | 2024.05.08 |
AnimatedVisibility()와 MutableTransitionState() (0) | 2024.05.07 |
Scaffold와 LazyColumn (1) | 2024.05.03 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!