[Android] 앱 아키텍처

정상준·2023년 6월 21일
0

앱 아키텍처

목록 보기
3/3
post-thumbnail

📚 모바일 앱 사용자 환경

Android App 은 여러 구성요소를 포함할 수 있고, 사용자는 짧은 시간내에 여러 앱과 상호작용 할 수 있다는 것을 고려해보면 앱은 사용자 중심의 다양한 워크플로 및 작업에 맞게 조정될 수 있어야 한다.
또한 스마트폰은 제한된 리소스를 가지고 있어 운영체제에서 새로운 앱을 위한 공간을 확보하도록 언제든지 일부 앱 프로세스를 종료해야 할 수 있다.
이러한 환경 조건을 고려해 볼 때 앱 구성요소는 개별적이고 비순차적으로 실행될 수 있으며, 운영체제나 사용자가 언제든지 앱 구성요소를 제거할 수 있다. 갑작스럽게 앱이 종료 될 수 있기에 앱 구성요소에 애플리케이션 데이터나 상태를 저장해서는 안 되며 앱 구성요소가 서로 종속되면 안 된다.

📚 일반 아키텍처 원칙

앱 아키텍처는 앱의 부분과 그 각 부분에 필요한 기능 간의 경계를 정의한다.

📝 관심사 분리

예시로 Activity와 Fragment에 모든 코드를 작성해선 안 된다. 이러한 UI 기반의 클래스는 UI 및 운영체제 상호작용을 처리하는 로직만 포함해야 한다. 최대한 가볍게 유지하여 구성요소 수명 주기와 관련된 많은 문제를 피하고 그러한 클래스의 테스트 가능성을 개선할 수 있다. 언제든지 사용자 또는 OS에 의해 클래스가 제거될 수 있다. 좋은 사용자 환경과 수월한 앱 관리 환경을 제공하기 위해선 의존성을 최소화 해야한다.

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

데이터 모델은 앱의 데이터를 나타내며, 앱의 UI 요소 및 기타 구성요소로부터 독립되어 있다.
즉, 이들은 UI 및 앱 구성요소 수명 주기와는 관련이 없지만 OS가 메모리에서 앱의 프로세스를 삭제하기로 결정하면 데이터 모델도 삭제됩니다.

지속 모델이 이상적인 이유는 다음과 같다.

  • Android OS에서 리소스를 확보하기 위해 앱을 제거해도 사용자 데이터가 삭제되지 않습니다.
  • 네트워크 연결이 취약하거나 연결되어 있지 않아도 앱이 계속 작동합니다.

📚 단일 소스 저장소

앱에서 새로운 데이터 유형을 정의할 때는 데이터 유형에 단일 소스 저장소(SSOT)를 할당해야 한다. SSOT는 데이터의 소유자이며, SSOT만 데이터를 수정하거나 변경할 수 있다. SSOT는 이를 위해 불변 유형을 사용하여 데이터를 노출하며, 다른 유형이 호출할 수 있는 이벤트를 수신하거나 함수를 노출하여 데이터를 수정한다.
이점 :

  • 특정 유형 데이터의 모든 변경사항을 한곳으로 일원화합니다.
  • 다른 유형이 조작할 수 없도록 데이터를 보호합니다.
  • 데이터 변경사항을 더 쉽게 추적할 수 있도록 합니다. 따라서 버그를 발견하기가 쉬워집니다.

📚 단방향 데이터 흐름

UDF에서 상태는 한 방향으로만 흐른다. 데이터 흐름을 수정하는 이벤트는 반대 방향으로 흐른다. Android에서 상태 또는 데이터는 일반적으로 계층 범위의 상위 범위 유형에서 하위 범위 유형으로 흐른다. 이벤트는 보통 하위 범위 유형에서 트리거되어 상응하는 데이터 유형의 SSOT에 도달한다.

📚 권장 앱 아키텍처

📝 UI 레이어

UI 레이어의 역할은 화면에 애플리케이션 데이터를 표시하는 것이다. 사용자 상호작용 또는 외부 입력으로 인해 데이터가 변할 때마다 변경사항을 반영하도록 UI가 업데이트되어야 한다.
UI 레이어는 다음 두 가지로 구성된다.

  • 화면에 데이터를 렌더링하는 UI 요소. 이러한 요소는 뷰 또는 Jetpack Compose 함수를 사용하여 빌드할 수 있다.
  • 데이터를 보유하고 이를 UI에 노출하며 로직을 처리하는 상태 홀더(예: ViewModel 클래스)

📝 데이터 레이어

앱의 데이터 레이어에는 비즈니스 로직이 포함되어 있다. 데이터 레이어는 레포지토리(저장소)와 데이터 소스로 이루워져 있다.
Repository : 이 저장소는 데이터 소스와 상호작용하고, 애플리케이션에서 필요한 데이터를 제공한다. 저장소는 비즈니스 로직을 캡슐화하고, 데이터 소스로부터 데이터를 검색하여 애플리케이션에서 사용할 수 있는 형식으로 변환한다.
Data Source : 데이터 소스는 실제 데이터를 저장하고 검색하는 역할을 한다. 데이터 소스는 다양한 유형의 데이터 저장소와 상호작용할 수 있다.

📚 구성요소 간 종속 항목 관리

앱의 클래스는 올바른 작동을 위해 다른 클래스에 종속된다. 특정 클래스의 종속 항목을 수집하는 데 다음 디자인 패턴 중 하나를 사용할 수 있다.

  • 종속 항목 주입(DI): 종속 항목 주입을 사용하면 클래스가 자신의 종속 항목을 구성할 필요 없이 종속 항목을 정의할 수 있다. 런타임 시 다른 클래스가 이 종속 항목을 제공해야 한다.(Hilt라이브러리)
  • 서비스 로케이터: 서비스 로케이터 패턴은 클래스가 자신의 종속 항목을 구성하는 대신 종속 항목을 가져올 수 있는 레지스트리를 제공한다.

📚 일반 권장사항

📝 앱 구성요소에 데이터를 저장

활동, 서비스, broadcast receiver와 같은 앱의 진입점을 데이터 소스로 지정하지 마라. 대신 그 진입점과 관련된 데이터 일부만 가져오도록 다른 구성요소에 맞춰 조정해야 한다.

📝 Android 클래스의 종속 항목을 줄임

앱 구성요소는 Context 또는 Toast 같은 Android 프레임워크 SDK API를 사용하는 유일한 클래스여야 한다. 다른 클래스와는 분리되어야 한다.

📝 앱의 다양한 모듈 간 책임이 잘 정의된 경계를 만듬

예시로 네트워크에서 데이터를 로드하는 코드를 코드베이스의 여러 클래스나 패키지 전체에 분산하면 안 된다.

📝 앱의 각 부분을 독립적으로 테스트하는 방법을 고려

예를 들어 네트워크에서 데이터를 가져오기 위해 API를 잘 정의하면 해당 데이터를 로컬 데이터베이스에 보존하는 모듈을 더 쉽게 테스트할 수 있다. 그러지 않고 두 모듈의 로직을 한 위치에 혼합하거나, 네트워크 코드를 전체 코드베이스에 분산하면 테스트가 불가능하지는 않을지라도 훨씬 더 어려워진다.

📝 가능한 한 관련성이 높은 최신 데이터를 보존

이렇게 하면 기기가 오프라인 모드일 때도 사용자가 앱의 기능을 이용할 수 있다. 끊김 없고 속도가 빠르더라도 혼잡한 곳에서는 수신 상태가 좋지 않을 수 있다.

📚 아키텍처의 이점

  • 앱의 전반적인 유지관리성, 품질, 견고성이 개선
  • 앱을 확장할 수 있다. 코드 충돌이 최소화되어 더 많은 인력과 팀이 동일한 코드베이스에 기여
  • 온보딩에 도움이 된다. 아키텍처는 프로젝트에 일관성을 부여하므로 새로운 팀원이 빠르게 업무를 시작하고 보다 짧은 시간에 효율을 높임
  • 테스트하기가 더 쉽다. 좋은 아키텍처는 테스트하기가 더 쉬운 간단한 유형을 사용하도록 지원
  • 잘 정의된 프로세스를 사용하여 버그를 체계적으로 조사
profile
안드로이드개발자

0개의 댓글