Jetpack Compose(7) - 아키텍쳐 레이어링

김재원·2022년 3월 18일
0

JetpackCompose

목록 보기
7/9
post-thumbnail

이 글은 JetpackCompose 공식문서 - 아키텍쳐 레이어링를 읽어보면서 정리한 글 입니다.

Jetpack Compose는 완전한 스택을 만들기 위해 다수의 모듈을 조합해 만들었습니다. Jetpack Compose를 구성하는 여러 모듈들을 이해하면 다음과 같은 작업이 가능합니다.

  • 적절한 수준의 추상화를 사용하여 앱 또는 라이브러리 빌드
  • 보다 세부적인 제어나 맞춤설정을 위해 낮은 수준으로 '드롭 다운'할 수 있는 경우 판단
  • 종속 항목 최소화

이번글에서는 Jetpack Compose를 구성하는 아키텍쳐 레이어와 관련 디자인의 핵심 원칙을 정리해 보도록 하겠습니다😌.

레이어

JetpackCompose의 기본 레이어는 다음과 같습니다.

위 그림에서는 밑으로 갈수록 하위 레이어 입니다. 각 레이어는 하위 수준에 기반하고, 상위 수준의 구성요소를 만들기 위해 결합합니다. 각 레이어는 하위 레이어의 공개 API를 기반으로 하여 모듈 경계를 확인하고 필요한 경우 레이어를 대체할 수 있게 해줍니다.

런타임(Runtime)

remember,mutableStateOf,@Composable주석,SideEffect와 같은 Compose 런타임의 기초를 제공합니다.
UI가 아닌 Compose의 트리 관리 기능만 필요한 경우 이 레이어에 바로 빌드하는 것이 좋습니다.

UI

UI레이어는 여러 개의 모듈(ui-text,ui-graphics,ui-tooling)로 구성됩니다. 이 모듈들은 LayoutNode,Modifier,입력 핸들러,맞춤 레이아웃,그리기같은 UI 툴킷의 기본 사항을 구현합니다.
UI툴킷의 기본 개념만 필요한 경우 이 레이어를 기반으로 빌드하는 것이 좋습니다.

기초(Foundation)

이 모듈은 Row,Column,LazyColumn,특정 동작인식 같은 디자인 시스템에 구속되지 않는 구성요소를 제공합니다.
자체 디자인 시스템을 만들 때는 이 레이어를 기반으로 빌드하는 것이 좋습니다.

머티리얼(Material)

이 모듈은 Compose UI에 머티리얼 디자인 시스템을 구현합니다. 머티리얼 디자인 시스템에는 테마 설정 시스템,스타일이 적용된 구성요소,물결표시,아이콘등이 있습니다.
앱에 Material 디자인을 사용할 경우 이 레이어를 기반으로 빌드합니다.

디자인 원칙

Compose의 기본원칙은 작고 집중된 기능들을 조립 혹은 구성하여 구현한다는 것입니다.

컨트롤

상위 수준의 구성요소는 자동으로 더 많은 작업을 실행하고, 개발자가 직접 제어할 수 있는 정도를 제한합니다. 더 많은 제어가 필요하다면 하위요소의 구성요소를 사용하도록 드롭 다운하면 됩니다.

색상을 애니메이션으로 표시하는 animateColorAsState API를 예시로 들어보겠습니다.

val color = animateColorAsState(if (condition) Color.Green else Color.Red)

구성요소를 항상 회색으로 시작해야하는 경우에는 animateColorAsState에서 지원해 주지 않기 때문에 Animatable API를 사용하도록 드롭다운 해야합니다.

상위 수준에 있는 animateColorAsState는 Animatable API를 기반으로 빌드됩니다.
하위 수준의 API를 사용하면 복잡하긴 해도 보다 세부적인 제어가 가능합니다.

맞춤설정

작은 구성요소를 조합하여 상위수준의 구성요소를 구현하면 더욱 쉽게 구성요소를 맞춤설정할 수 있습니다.
머티리얼에서 제공하는 Button을 예시로 들어보겠습니다.

@Composable
fun Button(
    // …
    content: @Composable RowScope.() -> Unit
) {
    Surface(/* … */) {
        CompositionLocalProvider(/* … */) { // set LocalContentAlpha
            ProvideTextStyle(MaterialTheme.typography.button) {
                Row(
                    // …
                    content = content
                )
            }
        }
    }
}

Button은 4가지 구성요소로 조합되었습니다.

  • Surface - 배경, 도형, 클릭 처리등을 제공하는 머티리얼
  • CompositionLocalProvider - 버튼이 사용되거나 중지될 때 콘텐츠의 알파를 변경
  • ProvideTextStyle - 기본 텍스트의 스타일을 설정
  • Row - 버튼 콘텐츠의 기본 레이아웃 정책을 제공

Button에서 매개변수 이외의 요소를 맞춤설정 하려면 수준을 드롭 다운하고 구성 요소를 포크하면 됩니다.
예를 들어 머티리얼 디자인에는 모든 버튼의 색깔을 단색이어야 한다고 되어있지만, 그라데이션 배경을 넣어야 한다는 상황이 있다고 가정해 봅시다. Button 매개변수에는 그라데이션을 넣는 매개변수가 없기 때문에 자체 구성요소를 빌드해야합니다.

@Composable
fun GradientButton(
    // …
    background: List<Color>,
    content: @Composable RowScope.() -> Unit
) {
    Row(
        // …
        modifier = modifier
            .clickable(/* … */)
            .background(
                Brush.horizontalGradient(background)
            )
    ) {
        CompositionLocalProvider(/* … */) { // set material LocalContentAlpha
            ProvideTextStyle(MaterialTheme.typography.button) {
                content()
            }
        }
    }
}

위 코드에서는 SurfaceRow로 대체하여 원하는 모양을 만들었습니다.

구성요소를 맞춤설정할때는 접근성 지원을 무시하는 등 기능을 저하시키지 않아야 합니다. 포크하는 구성요소를 가이드로 삼아 맞춤설정 해야합니다.

Compose는 최상위 수준의 구성요소는 가장 단순한 이름으로 정합니다.. 예를 들어 androidx.compose.material.Textandroidx.compose.foundation.text.BasicText를 기반으로 합니다. 이렇게 하면 상위 수준을 대체할 때 자체 구현에 가장 쉽게 찾을 수 있는 이름을 제공할 수 있습니다.

정확한 추상화 선택

재사용 가능한 계층화된 구성요소를 빌드한다는 Compose의 철학의 의미에는 항상 하위 수준의 구성요소만 추구해서는 안 된다는 뜻을 담고있습니다.

대다수의 상위 구성요소가 많은 기능을 제공하고, 접근성 지원과 같은 권장사항을 구현해 두었기 때문에 일반적으로 최상위 수준 구성요소를 기반으로 개발하는 것이 좋습니다.


이렇게 해서 Jetpack Compose의 아키텍쳐 레이어링에 대해 알아보았습니다. 다음 글에서는 Compose의 시멘틱에 대해 알아보도록 하겠습니다.
끝까지 읽어주셔서 감사합니다. 즐거운 개발 되세요🤗.

참고 Jetpack Compose 아키텍처 레이어링

profile
항상 배울 것을 찾는 개발자입니다🔥.

0개의 댓글