0Pricing
Android Academy · 강의

모듈화가 필요한 이유

빌드 속도, 소유권과 재사용성을 높입니다.

모듈화가 필요한 이유은(는) CoddyKit의 무료 Android Academy 강의입니다. 이것은 4개 중 1번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Android Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Android Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

모놀리스 문제

Android 앱이 커지면 모든 코드가 하나의 app 모듈에 들어 있는 경우가 많습니다. 이것이 바로 모놀리스입니다. 처음에는 편리하지만 시간이 지나면 문제가 됩니다. 변경할 때마다 같은 모듈을 건드리고, 빌드가 느려지며, 팀원들이 계속 서로의 작업과 충돌하게 됩니다.

모듈화란 하나의 큰 모듈을 여러 개의 작고 목적이 분명한 Gradle 모듈로 나누는 것을 의미합니다. 이 레슨에서는 팀이 모듈화를 사용하는 이유와 그로 인해 얻는 구체적인 이점을 알아봅니다.

모듈이란 실제로 무엇인가요

Gradle에서 모듈은 자체 build.gradle.kts 파일을 가진 독립적으로 빌드 가능한 코드 단위입니다. 앱에는 이미 하나 이상의 모듈이 있습니다. 바로 :app 모듈입니다. 모든 모듈은 settings.gradle.kts에서 선언합니다.

모듈을 추가하는 일은 간단히 포함하는 것뿐입니다. 각 모듈은 자체 빌드 결과물을 만들며 다른 모듈에 의존할 수 있습니다.

// settings.gradle.kts
include(":app")
include(":core:designsystem")
include(":core:data")
include(":feature:home")
include(":feature:profile")

이점 1: 더 빠른 빌드

가장 실용적인 이점은 빌드 속도입니다. Gradle은 모듈을 병렬로 빌드하고, 특히 입력이 변경되지 않은 모듈은 캐시하여 건너뛸 수 있습니다.

:feature:profile만 수정하면 Gradle은 다른 모든 모듈의 이미 빌드된 결과물을 재사용합니다. 모놀리스에서는 어떤 변경이든 앱 전체를 다시 컴파일하게 만들 수 있습니다.

  • 모듈 간 병렬 실행
  • 증분 빌드: 변경된 부분만 다시 빌드
  • 원격 빌드 캐시 적중률 향상
// gradle.properties
org.gradle.parallel=true
org.gradle.caching=true
org.gradle.configuration-cache=true

이점 2: 명확한 경계

모듈은 경계를 강제합니다. 한 모듈의 코드는 다른 모듈이 명시적으로 공개한 것만 볼 수 있습니다. 따라서 모든 클래스가 다른 모든 클래스에 마음대로 접근하는 복잡한 스파게티 구조를 방지할 수 있습니다.

api와 implementation Gradle 구성으로 가시성을 제어합니다. implementation은 의존성을 해당 모듈 내부에서만 사용할 수 있도록 하므로, 소비자가 실수로 이를 사용할 수 없습니다.

// feature/profile/build.gradle.kts
dependencies {
    // Exposed to whoever depends on :feature:profile
    api(project(":core:model"))

    // Private: hidden from consumers of this module
    implementation(project(":core:network"))
}

이점 3: 재사용

로직을 목적이 분명한 모듈에 배치하면 어디서든 재사용할 수 있습니다. 테마, 색상, 재사용 가능한 컴포저블을 담은 :core:designsystem 모듈을 모든 기능에서 공유할 수 있습니다.

같은 방식은 여러 앱에도 적용됩니다. 회사는 코드를 복사하는 대신 여러 제품에서 :core:network 모듈을 공유할 수 있습니다.

// Any feature can pull in shared building blocks
// feature/home/build.gradle.kts
dependencies {
    implementation(project(":core:designsystem"))
    implementation(project(":core:data"))
}

이점 4: 팀 소유권

모듈은 팀 소유권과 자연스럽게 연결됩니다. 결제 팀은 :feature:payments를 소유하고 프로필 팀은 :feature:profile을 소유합니다. 코드가 서로 다른 폴더와 빌드 파일에 있으므로 병합 충돌이 줄어들어 두 팀이 병렬로 작업할 수 있습니다.

CODEOWNERS 파일과 같은 도구는 모듈 경로를 기준으로 올바른 팀에 검토를 자동으로 요청할 수 있습니다.

# .github/CODEOWNERS
/feature/payments/   @org/payments-team
/feature/profile/    @org/profile-team
/core/designsystem/  @org/platform-team

이점 5: 가시성을 통한 캡슐화

모듈 내부에서 Kotlin의 internal 변경자는 강력한 기능을 발휘합니다. internal 클래스나 함수는 자신의 모듈 안에서만 보입니다. 다른 모듈에서는 이를 참조할 수 없습니다.

이를 통해 작은 공개 표면만 노출하고 구현 세부 정보를 숨길 수 있습니다. 하나의 거대한 모듈에서는 이런 제한을 강제하기 어렵습니다.

// In :core:data
// Public API other modules may use
fun interface UserRepository {
    suspend fun loadUser(id: String): User
}

// Hidden from other modules
internal class DefaultUserRepository(
    private val api: UserApi
) : UserRepository {
    override suspend fun loadUser(id: String) = api.fetch(id).toUser()
}

비용: 약간의 오버헤드

모듈화가 공짜인 것은 아닙니다. 각 모듈마다 관리해야 할 build.gradle.kts가 추가되고, 각 코드 조각을 어느 모듈이 소유할지 고민해야 합니다. 작은 앱을 지나치게 모듈화하면 얻는 이점 없이 번거로운 작업만 늘어납니다.

일반적인 기준은 다음과 같습니다. 빌드 시간이 문제가 되거나, 팀 간 충돌이 발생하거나, 재사용할 계층이 명확할 때 모듈화하세요. 주말에 취미로 만드는 앱에 모듈 30개가 필요한 경우는 거의 없습니다.

일반적인 모듈 구성

일반적이고 확장 가능한 구조는 모듈을 app, feature, core 계층으로 나눕니다. :app 모듈은 모든 요소를 연결하고, 기능 모듈은 사용자에게 표시되는 화면을 담으며, 핵심 모듈은 공유 인프라를 담습니다.

// Conceptual project tree
// app/                  <- single entry point, wires features
// feature/
//   home/
//   profile/
//   settings/
// core/
//   designsystem/       <- theme + reusable composables
//   data/               <- repositories
//   network/            <- Retrofit/Ktor
//   model/              <- shared data classes

규칙 플러그인으로 일관성 유지하기

모듈이 많을 때 모든 곳에 같은 Gradle 설정을 복사해 붙여 넣는 것은 함정입니다. 팀은 공유 설정을 규칙 플러그인으로 추출합니다(build-logic 모듈에 배치). 그러면 각 실제 모듈은 수십 줄을 반복하는 대신 플러그인 하나만 적용하면 됩니다.

Now in Android와 같은 대규모 오픈 소스 앱에서 이 패턴을 볼 수 있습니다. 지금은 목표만 기억하세요. 빌드 파일을 작고 일관되게 유지하는 것입니다.

// feature/home/build.gradle.kts
plugins {
    // One convention plugin sets up Android + Compose + Kotlin
    id("myapp.android.feature")
}

android { namespace = "com.myapp.feature.home" }

사고방식: 계층으로 생각하기

가장 유용한 정신 모델은 의존성이 아래쪽으로 흘러야 한다는 것입니다. 기능은 핵심 모듈에 의존하고 핵심 모듈은 기능에 의존하지 않습니다. :app 모듈은 가장 위에 위치하며 앱을 조립하는 데 필요한 모든 요소에 의존합니다.

이 방향을 일관되게 유지하면 모듈 그래프가 깔끔해지고 순환 의존성을 피할 수 있습니다. 순환 의존성은 이후 레슨에서 자세히 살펴봅니다.

// Allowed:  app -> feature -> core
// Forbidden: core -> feature (upward) or feature -> feature (sideways)
// app/build.gradle.kts
dependencies {
    implementation(project(":feature:home"))
    implementation(project(":feature:profile"))
}

빠른 확인

성장하는 Android 앱을 모듈화했을 때 팀이 얻는 가장 구체적이고 일상적인 이점은 다음 중 무엇인가요?

복습: 모듈화하는 이유

팀이 모놀리스를 모듈로 나누는 이유를 배웠습니다.

  • 병렬 실행과 증분 캐싱을 통한 더 빠른 빌드
  • api/implementation 및 internal을 사용한 명확한 경계
  • 디자인 시스템과 네트워크 같은 핵심 계층의 재사용
  • 병합 충돌을 줄이는 팀 소유권

추가 빌드 파일이라는 비용과 함께 다음의 핵심 원칙도 살펴보았습니다. 의존성은 아래쪽으로 흐르며 구조는 app -> feature -> core입니다. 다음에는 기능 모듈과 핵심 모듈 사이의 실제 경계를 그려 보겠습니다.

자주 묻는 질문

“모듈화가 필요한 이유” 강의는 무료인가요?

네 — “모듈화가 필요한 이유” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Android Academy 강의 전체를 잠금 해제할 수 있습니다. Android Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“모듈화가 필요한 이유”에서 뭘 배우나요?

빌드 속도, 소유권과 재사용성을 높입니다. 브라우저에서 직접 실행하는 실습 코드로 Android Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Android Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Android Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 1번째 강의입니다.

“모듈화가 필요한 이유” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Android Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Android Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 모듈화가 필요한 이유
  2. 기능 모듈과 핵심 모듈
  3. 모듈 종속성 관리
  4. 모듈 간 탐색
← Android Academy(으)로 돌아가기