Skip to content

Latest commit

 

History

History
126 lines (92 loc) · 5.94 KB

File metadata and controls

126 lines (92 loc) · 5.94 KB

SouZip 프로젝트 아키텍처

1. 모듈 구조 (Module Structure)

SouZip 안드로이드 프로젝트는 Android App Architecture를 기반으로 한 멀티모듈 구조를 채택하고 있습니다. 각 모듈은 기능 및 레이어별로 명확하게 분리되어 있으며, 이를 통해 코드의 재사용성을 높이고, 빌드 시간을 단축하며, 유지보수를 용이하게 합니다.

.
├── app
├── build-logic
├── presentation
├── domain
├── data
└── core

2. 의존성 그래프 (Dependency Graph)

모듈 간의 의존성 흐름은 아래와 같습니다. 의존성은 항상 바깥쪽 레이어에서 안쪽 레이어로 향하며, Domain 레이어는 다른 레이어에 대한 의존성을 갖지 않습니다.

graph TD
    subgraph App
        app
    end
    subgraph Presentation Layer
        presentation
    end
    subgraph Domain Layer
        domain
    end
    subgraph Data Layer
        data
    end
    subgraph Common/Shared
        core
    end

    app --> presentation
    app --> data
    app --> domain
    app --> core

    presentation --> domain
    presentation --> core

    data --> domain
    data --> core
Loading

3. 모듈 상세 설명 (Module Descriptions)

app

  • 애플리케이션의 진입점 역할을 하는 최상위 모듈입니다.
  • presentation, data 등 모든 모듈을 통합하고 최종적으로 하나의 Android 애플리케이션(.apk)으로 패키징됩니다.
  • Dagger Hilt를 사용한 전역 의존성 주입 설정 등 앱 실행에 필요한 초기화를 담당합니다.

build-logic

  • Gradle Convention Plugin을 사용하여 모듈별 Gradle 설정을 중앙에서 관리합니다.
  • 이를 통해 여러 모듈에 걸쳐 일관된 의존성 버전 관리와 플러그인 설정을 유지하여 build.gradle.kts 파일의 복잡성을 줄입니다.

presentation

  • UI와 관련된 모든 로직을 담당하는 모듈입니다.
  • 화면(Composable UI), 상태 관리(ViewModel), 네비게이션 등을 포함합니다.
  • MVI (Model-View-Intent) 아키텍처 패턴을 사용하여 UI 상태를 관리하며, domain 모듈의 Repository 인터페이스의 함수를 호출해 비즈니스 로직을 실행합니다.

domain

  • 순수한 Kotlin 모듈로, 애플리케이션의 핵심 비즈니스 로직을 포함합니다.
  • Models: 앱의 비즈니스 로직에 사용되는 모델 data class 입니다.
  • Repository Interfaces: 데이터 계층에서 구현해야 할 데이터 입출력 명세를 정의합니다.
  • 안드로이드 프레임워크에 대한 의존성이 없어 비즈니스 로직의 테스트가 용이합니다.

data

  • domain 모듈에서 정의한 Repository 인터페이스에 대한 구현체를 포함합니다.
  • Repository Pattern을 사용하여 데이터 소스를 추상화하고, 데이터의 출처(Remote, Local)를 숨깁니다.
  • Remote Data Source: Retrofit을 사용하여 서버 API와 통신합니다.
  • Local Data Source: Room DB, DataStore 등을 사용하여 디바이스 내부에 데이터를 저장하고 관리합니다.

core

  • 여러 모듈에서 공통으로 사용되는 유틸리티 및 기반 코드를 포함합니다.

4. 주요 아키텍처 및 디자인 패턴

AAC(Android App Architecture)

MVI (Model-View-Intent) on Presentation Layer

  • presentation 모듈은 단방향 데이터 흐름(Unidirectional Data Flow)을 따르는 MVI 패턴으로 구현되었습니다.
  • orbit-mvi 라이브러리를 사용하여 상태 관리를 효과적으로 처리합니다.
  • Intent: 사용자의 액션 또는 입력. 각 화면에서 사용될 Intent는 com.swyp.souzip.presentation.common.baseUiIntent를 상속받아 구현됩니다.
  • State: UI에 표시될 데이터. State가 변경되면 UI가 반응하여 다시 그려집니다. 각 화면에서 사용될 State는 com.swyp.souzip.presentation.common.baseUiState를 상속받아 구현됩니다. 구현되는 UiState의 프로퍼티들은 모두 Parcelable 하여야 합니다.
  • Side Effect: Toast, SnackBar, 화면 이동 등 일회성 이벤트를 처리합니다. 각 화면에서 사용될 SideEffect는 com.swyp.souzip.presentation.common.baseSideEffect를 상속받아 구현됩니다.
  • ViewModel: Intent를 받아 비즈니스 로직(UseCase)을 처리하고, 상태(State)를 업데이트합니다.
  • BaseViewModel.kt: MVI 패턴에 따라 orbit-mvi 라이브러리를 적용한 베이스 뷰모델 추상 클래스입니다. presentation 레이어의 모든 뷰모델이 상속받아 구현하여 모든 뷰모델이 orbit이 적용된 mvi 패턴을 따르도록 강제합니다. UI에서 뷰모델의 로직을 호출하는 방법은 오직 onIntent() 함수로 유일하며, 각 뷰모델에서 구현되는 다른 함수는 모두 private 접근지정자를 갖습니다.

Repository Pattern

  • data 모듈은 Repository Pattern을 사용하여 데이터 소스를 추상화합니다.
  • ViewModel은 데이터가 어디서 오는지(네트워크, DB, 캐시 등) 알 필요 없이 domain의 Repository 인터페이스에만 의존하므로, 데이터 소스의 변경에 유연하게 대처할 수 있습니다.

데이터 흐름 (Data Flow)

  • 데이터는 Remote(DTO) -> Repository -> Domain(Model) -> Presentation(UI State) 순서로 흐르며, 각 계층의 경계를 넘어갈 때 필요한 모델로 매핑됩니다.. 이를 통해 각 레이어는 자신에게 필요한 데이터 형태에만 집중할 수 있습니다.