Jetpack UI 레이어 정보

day_0893·2023년 9월 3일

JetPackTutorial

목록 보기
8/9

디벨로퍼URL

UI 레이어

UI의 역할은 화면에 애플리케이션 데이터를 표시하고 상호 작용의 기본 지점으로도 가능하다는 것입니다. (상호 작용의 예: 버튼누르기, 네트워크 응답)
실제 데이터와 UI에 표시되는 정보가 다를 수 있습니다.(예: 두 데이터 소스를 조합하여 표시하거나 일부만 표시하는 경우)

UI elements, State holders

  • UI 레이어 아키텍처
    UI라는 용어는 사용하는 API(JetpackCompose 또는 뷰) 와 관계 없이 데이터를 표시하는 Acitivty Fragment와 같은 UI 요소를 가리킵니다.
    데이터 레이어의 역할은 데이터를 보유하고 관리하며 앱 데이터에 액세스할 권한을 제공하는 것이므로 UI 레이어에서 다음 단계를 실행합니다.
  1. 앱 데이터를 사용 하고 UI에 쉽게 렌더링 될 수 있는 데이터로 변환
  2. UI 렌더링 가능 데이터를 사용하고 사용자에게 표시할 수 있는 요소로 변환
  3. 이렇게 조합된 UI 요소의 사용자 입력 이벤트를 사용하고 입력 이벤트의 결과를 필요에 따라 UI 데이터에 반영한다.
  • UI 상태 정의
    NewsUiState UI 상태
    isSignedIn: 로그인 상태
    isPremium: 프리미엄 상태
    newsItems: 뉴스 아이템 리스트 상태
    userMessage: 뉴스 메시지 리스트

NewsItemUiState 뉴스 아이템
title: 제목
body: 내용
bookmarked: 북마크 상태

data class NewsUiState(
    val isSignedIn: Boolean = false,
    val isPremium: Boolean = false,
    val newsItems: List<NewsItemUiState> = listOf(),
    val userMessages: List<Message> = listOf()
)

data class NewsItemUiState(
    val title: String,
    val body: String,
    val bookmarked: Boolean = false,
    ...
)
  • 불변성
    위 예에서 UI 상태 정의는 변경할 수 없습니다.(val) 불변성의 주요 이점은 변경 불가능한 객체가 순간의 애플리케이션 상태를 보장한다는 점입니다. 덕분에 UI는 상태를 읽고 이에 따라 UI 요소를 업데이트 하는 한가지 역할에 집중할 수 있습니다. 따라서 UI 자체가 데이터의 유일한 소인 경우를 제외하고 UI에서 UI상태를 직접 수정해서는 안 됩니다.
    예를 들어 NewsItemUiState 객체에 있는 bookmarked 플래그가 Activity 클래스에서 업데이트 되면 이 플래그는 북마크된 기사 상태의 소스로서 데이터 레이어와 경합합니다.
  • 이 가이드의 이름 지정 규칙
    이 가이드에서는 화면의 기능이나 묘사되는 화면의 부분에 따라 UI 상태 클래스의 이름을 지정합니다. 규칙은 다음과 같습니다.
    기능+UiState
    예를 들어 뉴스를 표시하는 화면의 상태는 NewsUiState 이고 뉴스 항목 목록에 있는 뉴스 항목의 상태는 NewsItemUiState 일 수 있습니다.

단방향 데이터 흐름으로 상태 관리

이전 섹션에서는 UI 상태가 UI 렌더링에 필요한 세부정보가 포함된 변경 불가능한 스냅샷임을 확인했씁니다. 하지만 데이터의 동적 특성에 따라 상태는 시간이 지나면서 변경될 수 있으며 이는 앱을 채우는 데 사용되는 기본 데이터를 수정하는 사용자 상호작용이나 기타 이벤트로 이벤트로 인해 발생하기도 합니다.

여기서 중재 요소가 각 이벤트에 적용할 로직을 정의하고 UI 상태를 만들기 위해 지원데이터 소스에 필요한 변환을 실행하는 상호작용을 처리하는 이점이 있을 수 있습니다. 상호작용과 이에 따른 로직이 UI 자체에 포함될 수 있지만 UI가 이름에서 알 수 있는 것 이상의 역할(예 데이터 소유자, 생성자, 변환자)을 담당하기 시작하면 빠르게 복잡해 질 수 있습니다. 궁극적으로 UI 에 주는 부담을 줄여야합니다. UI 상태가 매우 단순하지 않은 이상 UI 역할은 오직 UI 상태를 사용 및 표시하는 것 이어야합니다. -> UDF 단방향 데이터 흐름

  • 상태 홀더
    UI 상태를 생성하는 역할을 담당하고 생성 작업에 필요한 로직을 포함하는 클래스를 상태홀더라고 합니다. 상태 홀더의 크기는 하단의 앱바 같은 단일 위젯부터 전체화면이나 탐색 대상에 이르기까지 관리 대상UI 요서 범위에 따라 다양합니다.

전체 화면이나 탐색 대상의 경우 일반적인 구현은 ViewModel의 인스턴스이지만 애플리케이션의 요구사항에 따라 간단한 클래스로도 충분할 수 있습니다.


단방향 데이터 흐름(UDF)의 작동 방식을 보여주는 다이어그램
Unidiredical Data Flow

  • ViewModel이 UI 에 사용될 상태를 보유하고 노출합니다. UI 상태는 ViewModel에 의해 변환된 애플리케이션 데이터 입니다.
  • UI 가 ViewModel에 사용자 이벤트를 알립니다.
  • ViewModel이 사용자 작업을 처리하고 상태를 업데이트 합니다.
  • 업데이트된 상태가 렌더링할 UI에 다시 제공됩니다.
  • 상태 변경을 야기하는 모든 이벤트에 위의 작업이 반복됩니다.


사용자의 기사 북마크 요청은 상태 변경을 야기할 수 있는 이벤트의 예입니다.
상태 생성자의 경우 UI 상태의 모든 필드를 채우고 UI가 완전히 렌더링 되는데 필요한 이벤트를 처리하기 위해 모든 필수 로직을 정의하는 역할은 ViewModel이 담당합니다.

  • 로직의 유형
    기사 북마크는 앱에 가치를 부여하므로 비즈니스 로직입니다.
    • 비지니스 로직: 앱 데이터에 대한 제품 요구사항의 구현입니다. 일반적으로 비지니스 로직은 UI레이어에 배치되지 않고 도메인 또는 데이터 레이어에 배치됩니다.

    • UI 동작 로직 또는 UI 로직: 화면에서 상태 변경을 표시하는 방법입니다. 예를 들어 Android Resource를 사용하여 화면에 표시할 올바른 텍스트를 가져오거나, 사용자가 버튼을 클릭할 때 특정 화면으로 이동하거나 토스트메시지 또는 스택바를 사용하여 화면에 사용자 메시지를 표시합니다.

      특히 Context 같은 UI 유형의 경우 UI 로직은 ViewModel이 아닌 UI 에 있어야합니다. 테스트의 가능성을 높이고 문제 구분에 도움이 되도록 UI 로직을 다른 클래스에 위임하고자 하며 UI 가 복잡한 경우 간단한 클래스를 상태 홀더로 만들 수 있습니다. UI에서 생성된 간단한 클래스는 UI의 생명 주기를 따르기 따문에 Android SDK 종속 항목을 사용할 수 있습니다. ViewModel의 수명주기는 더 깁니다.

  • UDF 를 사용하는 이유
    • 데이터 일관성: UI용 정보 소스가 하나입니다.
    • 테스트 가능성: 상태 소스가 분리되므로 UI와 별개로 테스트할 수 있습니다.
    • 유지 관리성: 상태 변경은 잘 정의된 패턴을 따릅니다. 즉 변경은 사용자 이벤트 및 데이터를 가져온 소스 모두의 영향을 받습니다.

UI 상태 노출

UDF 를 사용하여 상태 생성 관리를 하기 떄문에 스트림으로 간주할 수 있습니다. LiveData 또는 StateFlow와 같이 관찰 가능한 데이터 홀더에 UI 상태를 노출해야합니다.

class NewsViewModel(...) : ViewModel() {

    val uiState: StateFlow<NewsUiState> = …
}

관찰 가능한 데이터 홀더로서의 LiveData에 관해서는 이 Codelab에서 소개합니다. Kotlin 흐름에 관한 비슷한 소개는 Android의 Kotlin 흐름을 참고하세요.

0개의 댓글