안드로이드 - 앱 아키텍처 가이드

이우건·2023년 3월 13일
0

안드로이드

목록 보기
4/20

아키텍처의 의미

  • 프로그램을 변경하는데 드는 비용

    프로그램의 새로운 변경사항을 추가하는데 기존의 코드를 변경해야 하는 경우 기존의 코드를 약간만 변경해도 변경사항을 추가할 수 있다면 높은 생산성을 가진다.

모바일 앱 사용자 환경

일반적인 Android 앱에는 Activity, Fragment, Service, content Provider, Broadcast receiver를 비롯하여 앱 구성요소가 포함된다. 개발자는 App menifast에서 이러한 앱 구성요소 대부분을 선언하며, Android OS에서 이 파일을 사용하여 기기의 전반적인 사용자 환경에 앱을 통합하는 방법을 결정한다.

=> 앱은 사용자 중심의 다양한 워크플로 및 작업에 맞게 조정될 수 있어야 한다.

또한 휴대기기는 리소스가 제한되어 있으므로, 운영체제에서 새로운 앱을 위한 공간을 확보하도록 언제든지 일부 앱 프로세스를 종료해야 할 수 있다.

-> 이러한 이벤트는 직접 제어할 수 없다.
-> 앱 구성요소에 데이터나 상태를 저장해서는 안되며, 서로 종속되면 안된다.

관심사 분리

따라서 가장 중요한 원칙은 관심사 분리이다.

  • Activity 또는 Fragment에 모든 코드를 작성하는 실수는 흔히 일어난다. 이러한 UI 기반의 클래스는 UI 및 운영체제 상호작용을 처리하는 로직만 포함해야한다.
  • Activity 및 Fragment 구현은 소유 대상이 아니며 Android OS와 앱 사이의 계약을 나타내도록 이어주는 클래스일 뿐이다.
  • OS는 메모리 부족과 같은 시스템 조건으로 언제든지 클래스를 제거할 수 있다.
  • 이러한 클래스에 대한 의존성을 최소화하는 것이 좋다.

데이터 모델에서 UI 도출하기

  • 데이터 모델은 앱의 데이터를 나타낸다.
  • EX) JSON Format 데이터를 data class를 활용하여 객체를 만들고 view에 할당하여 UI를 그린다.
  • 지속 모델이 이상적인 이유
    • Android OS에서 리소스를 확보하기 위해 앱을 제거해도 사용자 데이터가 삭제되지 않는다.
    • 네트워크 연결이 취약하거나 연결되어 있지 않아도 앱이 계속 작동한다.
      => 데이터 베이스를 활용한다.

권장 앱 아키텍처

Layer : 관심사에 따라서 분리된 계층
-> 같은 Layer라면 같은 성격을 가진 코드들이 모여있어야 한다.

  • 화면에 애플리케이션 데이터를 표시하는 UI Layer
  • 앱의 비즈니스 로직을 포함하고 애플리케이션 데이터를 노출하는 Data Layer

UI와 Data Layer 간의 상호작용을 간소화하고 재사용하기 위한 Domain Layer를 추가할 수 있다.

UI Layer

UI Layer의 역할은 화면에 애플리케이션 데이터를 표시하는 것이다. 사용자 상호작용(Ex. 버튼 누르기) 또는 외부 입력(Ex. 네트워크 응답)으로 인해 데이터가 변할 때마다 변경사항을 반영하도록 UI가 업데이트 되어야 한다.

UI는 데이터 레이어에서 가져온 애플리케이션 상태를 시각적으로 나타낸다.

하지만 일반적으로 데이터 레이어에서 가져오는 어플리케이션 데이터는 표시해야 하는 정보와 다른 형식이다. 예를 들어 UI용으로 데이터의 일부만 필요하거나 사용자에게 관련성 있는 정보를 표시하기 위해 서로 다른 두 데이터 소스를 병합해야 할 수도 있다. 적용하는 로직과는 관계없이 완전히 렌더링하는 데 필요한 모든 정보를 UI에 전달해야한다.

UI 레이어는 애플리케이션 데이터 변경사항을 UI가 표시할 수 있는 형식으로 변환한 후에 표시하는 파이프라인이다.

UI 레이어는 다음 두 가지로 구성된다.

  • 화면에 데이터를 렌더링하는 UI 요소(xml view). 이러한 요소는 View 또는 Jetpack Compose 함수를 사용하여 빌드할 수 있다. (UI elements)
  • 상태와 관련된 데이터를 보유하고 이를 UI에 노출하며 로직을 처리하는 State holders (Ex. ViewModel 클래스)

UI Layer Architecture

UI라는 용어하는 사용하는 API(view 또는 Jetpack Compose)와 관계없이 Activity 및 Fragment와 같은 UI 요소를 가리킨다.
데이터 레이어의 역할은 앱 데이터를 보유하고 관리하며 앱 데이터에 액세스할 권한을 제공하는 것이므로 UI 레이어에서 다음 단계를 실행해야 한다.

  1. 앱 데이터를 사용하고 UI에서 쉽게 렌더링할 수 있는 데이터로 변환한다.
  2. UI 렌더링 가능 데이터를 사용하고 사용자에게 표시할 UI 요소로 변환한다.
  3. 이럽게 조합된 UI 요소의 사용자 입력 이벤트를 사용하고 입력 이벤트의 결과를 필요에 따라 UI 데이터에 반영한다.
  4. 1~3단계를 필요한만큼 반복한다.

UI 상태 정의

  • 앱에서 사용자가 봐야 한다고 지정하는 항목
  • UI 상태가 변경되면 즉시 UI에 반영된다.
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 상태 정의는 변경할 수 없다. 불변성의 주요 이점은 변경 불가능한 객체가 순간의 애플리케이션 상태를 보장한다는 점이다.

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

state Holders

UI 상태를 생성하는 역할을 담당하고 생성 작업에 필요한 로직을 포함하는 클래스를 상태 홀더라고 한다.
전체 화면이나 탐색 대상의 경우 일반적인 구현은 ViewModel의 인스턴스이지만 애플리케이션의 요구사항에 따라 간단한 클래스로도 구현할 수 있다.

UI와 ViewModel 클래스 사이의 상호작용은 대체로 이벤트 입력과 입력의 후속 상태인 출력으로 간주될 수 있으므로 관계는 다음 다이어그램과 같다.

상태가 아래로 향하고 이벤트는 위로 향하는 패턴을 단방향 데이터 흐름(UDF)라고 한다. 이 패턴이 앱 아키텍처에 미치는 영향은 다음과 같다.

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

UI 상태 노출

UI 상태를 정의하고 이 상태의 생성을 관리할 방법을 결정한 후에는 생성된 상태를 UI에 표시하는 단계를 진행한다. UDF를 사용하여 상태 생성을 관리하므로 생성된 상태를 스트림으로 간주할 수 있다.

LiveData 또는 StateFlow를 통해 상태를 노출한다.

UI 상태 사용

UI에서 UiState(data class) 객체의 스트림을 사용하려면 사용 중인 observable 데이터 유형에 터미널 연산자를 사용한다. 예를 들어 LiveData의 경우 observe() 메서드를 사용하고 Kotlin Flow의 경우 collect() 메서드나 이 메서드의 변형을 사용한다.

UI에서 observable 데이터 홀더를 사용할 때는 UI의 수명 주기를 고려해야 한다. 수명 주기를 고려해야 하는 이유는 사용자에게 view가 표시되지 않을 때 UI가 UI상태를 관찰해서는 안 되기 때문이다.

LiveData를 사용하면 LifecycleOwner가 수명 주기 문제를 암시적으로 처리한다.
Flow를 사용할 때는 적절한 코루틴 범위와 repeatOnLifecycle API로 처리하는 것이 좋다.

Data Layer

데이터 영역에는 애플리케이션 데이터 및 비즈니스 로직이 포함된다.
비즈니스 로직은 앱에 가치를 부여하는 요소로, 애플리케이션의 데이터 생성, 저장, 변경 방식을 결정하는 실제 비즈니스 규칙으로 구성된다.

Data Layer Architecture

데이터 영역은 0개부터 여러 개의 데이터 소스를 각각 포함할 수 있는 저장소로 구성된다. 앱에서 처리하는 다양한 유형의 데이터 별로 저장소 클래스를 만들어야한다. 예를 들어 영화 관련 데이터에는 MoviesRepository 클래스를 만들거나 결게 관련 데이터에는 PaymentRepository 클래스를 만들 수 있다.

Repository 클래스에서 담당하는 작업은 다음과 같다.

  • 앱의 나머지 부분에 데이터 노출
  • 데이터 변경사항을 한 곳에 집중
  • 여러 데이터 소스 간의 충돌 해결
  • 앱의 나머지 부분에서 데이터 소스 추상화(Interface)
  • 비즈니스 로직 포함

각 데이터 소스 클래스는 파일, 네트워크 소스, 로컬 데이터베이스와 같은 하나의 데이터 소스만 사용해야 한다. 데이터 소스 클래스는 데이터 작업을 위해 애플리케이션과 시스템 간의 가교 역할을한다.

계층 구조의 다른 레이어는 데이터 소스에 직접 액세스해서는 안된다. 데이터 영역의 진입점은 항상 저장소 클래스여야 한다.

참조 : 앱 아키텍처 가이드
앱 아키텍처 가이드 - 브런치

profile
머리가 나쁘면 기록이라도 잘하자

0개의 댓글