본문 바로가기

안드로이드/클린 아키텍처

[안드로이드 클린 아키텍처 시리즈] 프로젝트 구조 설정 #4


1. 클린 아키텍처 프로젝트 구조

안녕하세요. 지난 시간까지는 안드로이드 클린 아키텍처의 이론에 대해서 공부했는데, 이번 포스팅부터는 안드로이드 클린 아키텍처를 직접 구현하는 과정을 설명하겠습니다. 안드로이드 클린 아키텍처를 구현할 때 모듈화는 각 계층의 독립성을 보장하고, 의존성을 명확하게 관리하는 데 중요한 역할을 한다고 설명했습니다. 먼저, 클린 아키텍처의 주요 계층인 UI Layer, Domain Layer, Data Layer 프로젝트 구조를 구현하겠습니다.

각 계층을 모듈화 한 모습


계층들을 모듈화함으로써, 각 계층은 서로 독립적으로 개발, 테스트 및 유지보수될 수 있습니다.
아래 순서대로 포스팅을 진행하겠습니다.

  1. Domain 모듈 생성
  2. Data 모듈 생성
  3. 클린 아키텍처 계층별 의존성 설정

1. Domain 모듈 생성

안드로이드 스튜디오에서는 각 계층을 별도의 모듈로 구성하여 의존성을 관리합니다. File > New > New Module을 선택하여 새 모듈을 생성합니다. Domain Layer용 모듈을 생성할 때는 안드로이드 프레임워크나 라이브러리에 의존하지 않는 'Java or Kotlin Library'를 선택합니다. Domain Layer는 어떤 플랫폼에도 종속되지 않는 계층이기 때문에 아래와 같은 이유로 'Android Library'로 생성하지 않고 'Java or Kotlin Library'로 생성합니다.

'Java or Kotlin Library'를 선택해서 Domain Layer를 생성하는 모습

1-1. Domain Layer에서 'Java or Kotlin Library'를 선택하는 이유

Domain Layer를 순수 Kotlin/Java 라이브러리로 구현하는 이유는, 비즈니스 로직을 플랫폼에서 독립적으로 유지하여, 테스트 용이성을 높이고, 코드의 재사용성과 유지보수성을 향상하기 위함입니다. 이로 인해, 비즈니스 규칙이 UI나 데이터 저장소의 구현 세부 사항으로부터 분리되며, 애플리케이션의 다른 부분이 변경되어도 비즈니스 로직에 영향을 주지 않습니다.

2. Data 모듈 생성

Data Layer에서는 데이터 저장소와의 상호작용을 담당하는데, 안드로이드 플랫폼에 특화된 기능과 API를 활용하기 위해서 반드시 'Android Library'를 선택해서 모듈을 생성해야 합니다.

'Android Library'를 선택해서 Data Layer를 생성하는 모습

2-1. Data Layer에서 'Android Library'를 선택해서 모듈을 생성하는 이유

Data Layer를 Android Library로 구현하는 이유는, 안드로이드 기능과 API를 사용하기 위해서입니다. 로컬 데이터베이스 접근(Room, SQLite), Shared Preferences, 네트워크 통신(Retrofit, OkHttp), 백그라운드 작업(WorkManager, JobScheduler), 그리고 안드로이드의 Context 접근 등이 포함됩니다. 이러한 기능들은 순수 Kotlin/Java 라이브러리에서는 사용할 수 없기 때문에 데이터 관리와 관련된 작업을 효과적으로 수행하기 위해 Android Library가 필요합니다.

3. 클린 아키텍처 계층별 의존성 설정

클린 아키텍처에서 의존성은 바깥쪽 계층에서 안쪽 계층으로 향합니다. 안쪽 계층은 바깥쪽 계층에 대해 알지 못하며, 바깥쪽 계층은 안쪽 계층의 인터페이스를 통해 데이터를 주고받습니다. Kotlin DSL을 사용하는 Gradle 설정에서 의존성을 구성하는 방법을 각 계층별로 살펴보겠습니다.

3-1. Domain Layer 의존성 설정

Domain Layer는 애플리케이션의 비즈니스 로직을 담당하며, 다른 계층에 의존하지 않습니다. 따라서, Domain Layer의 build.gradle.kts 파일에는 다른 계층에 대한 의존성이 포함되지 않습니다.

3-2. Data Layer 의존성 설정

Data Layer는 네트워크 통신, 로컬 데이터베이스 접근 등 데이터를 처리하는 로직을 담당하며, Domain Layer에 정의된 인터페이스를 구현합니다. 따라서, Data Layer는 Domain Layer에 의존합니다.

dependencies {
    implementation(project(":domain")) // Domain Layer에 대한 의존성
}

3-3. UI Layer 의존성 설정

UI Layer는 사용자에게 데이터를 표시하고, 사용자 입력을 처리합니다. Domain Layer에 정의된 유스케이스를 사용하여 사용자와의 상호작용을 기반으로 비즈니스 로직을 실행하고, 로컬 데이터베이스나 프리퍼런스에 직접 접근하는 등 특정 데이터 처리 작업을 위해 Data Layer의 기능을 직접 사용할 수도 있습니다. 따라서, UI Layer는 Domain Layer, Data Layer에 의존합니다.

dependencies {
    implementation(project(":domain")) // Domain Layer에 대한 의존성
    implementation(project(":data"))   // Data Layer에 대한 의존성
}

2. 클린 아키텍처 프로젝트 구조 설정 정리

각 계층의 명확한 역할 분리와 적절한 의존성 관리를 통해, 클린 아키텍처는 애플리케이션의 핵심 비즈니스 로직을 효과적으로 보호하고, 변화에 유연하게 대응할 수 있는 견고한 소프트웨어 아키텍처를 제공합니다. Gradle Kotlin DSL을 사용한 의존성 설정은 이러한 아키텍처 원칙을 실제 프로젝트에 적용하는 데 있어 효과적인 수단이라고 생각합니다.

다음 포스팅에서는 Domain Layer에 대해 더 자세히 다뤄보겠습니다.