여러 Gradle 모듈이 있는 프로젝트를 다중 모듈 프로젝트라고 합니다. 이 가이드에는 다중 모듈 Android 앱 개발을 위한 권장사항과 권장 패턴이 포함되어 있습니다.
증가하는 코드베이스 문제
코드베이스가 계속 증가하다 보면 시간이 지남에 따라 확장성, 가독성 및 전반적인 코드 품질이 떨어지는 경우가 많습니다. 그 원인은 코드베이스 규모가 커지고 있음에도 불구하고 유지관리 담당자가 쉽게 유지관리할 수 있는 구조를 적용하기 위한 적극적인 조치를 취하지 않기 때문입니다. 모듈화는 유지관리 가능성을 개선하고 이러한 문제를 방지할 수 있는 방식으로 코드베이스를 구조화하는 방법입니다.
모듈화란?
모듈화는 코드베이스를 느슨하게 결합된 독립적인 부분으로 구성하는 방법입니다. 각 부분이 모듈에 해당합니다. 각 모듈은 독립적이며 명확한 역할을 합니다. 하위 문제를 해결하기 위해 문제를 더 작고 쉬운 문제로 나누면 대형 시스템 설계와 유지보수의 복잡성이 줄어듭니다.
그림 1: 샘플 다중 모듈 코드베이스의 종속 항목 그래프
모듈화의 이점
모듈화의 이점은 많지만 모두 코드베이스의 유지관리 가능성과 전반적인 품질을 개선하는 데 중점을 둡니다. 다음 표에는 주요 이점이 요약되어 있습니다.
이점
요약
재사용성
모듈화를 사용하면 코드를 공유하고 동일한 기반을 토대로 여러 앱을 빌드할 수 있습니다. 모듈은 사실상 구성요소의 역할을 합니다. 앱은 기능의 총합으로, 각 기능은 별도 모듈 형태로 구성됩니다. 특정 모듈이 제공하는 기능은 특정 앱에 사용되거나 사용되지 않을 수 있습니다. 예를 들어, :feature:news가 전체 버전과 Wear 앱에는 있고 데모 버전에는 없을 수 있습니다.
엄격한 공개 상태 제어
모듈을 사용하면 코드베이스의 다른 부분에 노출할 내용을 쉽게 제어할 수 있습니다. 공개 인터페이스를 제외한 모든 항목을 internal 또는 private으로 표시하여 모듈 외부에서 사용하지 못하도록 할 수 있습니다.
맞춤설정 가능한 전송
Play Feature Delivery는 App Bundle의 고급 기능을 사용하여 앱의 특정 기능을 조건부로 또는 주문형으로 전송할 수 있도록 합니다.
모듈화의 이점은 모듈식 코드베이스에서만 얻을 수 있습니다.
다음 이점은 다른 기술을 사용해서도 얻을 수 있지만 모듈화를 사용하면 더욱 극대화할 수 있습니다.
이점
요약
확장성
긴밀히 결합된 코드베이스에서는 하나의 변경사항이 관련 없어 보이는 코드 부분까지도 연쇄적으로 바꾸어 놓을 수 있습니다. 적절히 모듈화된 프로젝트는 관심사 분리 원칙을 수용하므로 결합을 제한합니다. 이를 통해 참여자는 더 큰 자율성으로 더 많은 권한을 얻게 됩니다.
소유권
모듈은 자율성을 보장하는 것 외에 책임성을 부여하는 데도 사용할 수도 있습니다. 모듈에는 코드 유지관리, 버그 수정, 테스트 추가, 변경사항 검토 등을 담당하는 전용 소유자를 둘 수 있습니다.
캡슐화
캡슐화는 코드의 각 부분이 다른 부분에 관한 지식을 최소한으로만 갖고 있어야 함을 의미합니다. 분리된 코드가 읽고 이해하기가 더 쉽습니다.
테스트 가능성
테스트 가능성은 코드를 얼마나 쉽게 테스트할 수 있는지를 나타냅니다. 테스트 가능한 코드베이스는 구성요소를 격리된 상태로 쉽게 테스트할 수 있는 코드베이스입니다.
빌드 시간
증분 빌드, 빌드 캐시 또는 병렬 빌드와 같은 일부 Gradle 기능은 모듈성을 활용하여 빌드 성능을 개선할 수 있습니다.
일반적인 문제
코드베이스의 세분화는 코드베이스가 모듈로 구성된 정도를 나타냅니다. 코드베이스가 세분화되면 될수록 모듈이 더 작고 숫자가 늘어납니다. 모듈식 코드베이스를 설계할 때 세분화의 수준을 결정해야 합니다. 그렇게 하려면 코드베이스의 크기와 상대적 복잡성을 고려해야 합니다. 너무 세분화되면 오버헤드가 가중되고 너무 대략적이면 모듈화의 이점이 줄어듭니다.
일반적인 몇 가지 문제는 다음과 같습니다.
너무 세분화됨: 빌드 복잡성과 상용구 코드가 늘어남으로써 모든 모듈에서 일정량의 오버헤드가 발생합니다. 복잡한 빌드 구성으로 인해 모듈 간에 일관된 구성을 유지하기가 어렵습니다. 상용구 코드가 너무 많아 관리하기 어렵고 번거로운 코드베이스가 됩니다. 오버헤드가 확장성 개선에 해가 되는 경우 일부 모듈을 통합하는 것이 좋습니다.
너무 대략적임: 반대로 모듈이 너무 커지면 또 하나의 모놀리식이 될 수 있으며 모듈성이 제공하는 이점을 놓칠 수 있습니다. 예를 들어 작은 프로젝트에서는 데이터 영역을 단일 모듈 내에 넣어도 괜찮습니다. 그러나 크기가 커지면 저장소와 데이터 소스를 독립형 모듈로 분리해야 할 수 있습니다.
너무 복잡함: 프로젝트를 모듈화하는 것이 항상 적합한 것은 아닙니다. 결정적 요소는 코드베이스의 크기입니다. 프로젝트가 특정 기준점 이상으로 확장될 것 같지 않으면 확장성 및 빌드 시간 면의 이점은 누릴 수 없습니다.
모듈화가 적합한 기법인가요?
재사용성, 엄격한 공개 상태 제어 등의 이점이 필요하거나 Play Feature Delivery를 사용하려면 모듈화가 필수입니다. 그러지는 않더라도 확장성과 소유권, 캡슐화 또는 빌드 시간 개선을 통한 이점을 얻으려면 모듈화를 고려하는 것이 좋습니다.
이 페이지에 나와 있는 콘텐츠와 코드 샘플에는 콘텐츠 라이선스에서 설명하는 라이선스가 적용됩니다. 자바 및 OpenJDK는 Oracle 및 Oracle 계열사의 상표 또는 등록 상표입니다.
최종 업데이트: 2025-08-17(UTC)
[null,null,["최종 업데이트: 2025-08-17(UTC)"],[],[],null,["# Guide to Android app modularization\n\nA project with multiple Gradle modules is known as a multi-module project. This\nguide encompasses best practices and recommended patterns for developing\nmulti-module Android apps.\n| **Note:** This page assumes a basic familiarity with the [recommended app\n| architecture](/topic/architecture).\n\nThe growing codebase problem\n----------------------------\n\nIn an ever-growing codebase, scalability, readability, and overall code quality\noften decrease through time. This comes as a result of the codebase increasing\nin size without its maintainers taking active measures to enforce a structure\nthat is easily maintainable. Modularization is a means of structuring your\ncodebase in a way that improves maintainability and helps avoid these problems.\n\nWhat is modularization?\n-----------------------\n\nModularization is a practice of organizing a codebase into loosely coupled and\nself contained parts. Each part is a module. Each module is independent and\nserves a clear purpose. By dividing a problem into smaller and easier to solve\nsubproblems, you reduce the complexity of designing and maintaining a large\nsystem.\n**Figure 1**: Dependency graph of a sample multi-module codebase\n\nBenefits of modularization\n--------------------------\n\nThe benefits of modularization are many, though they each center upon improving\nthe maintainability and overall quality of a codebase. The following table\nsummarizes the key benefits.\n\n| Benefit | Summary |\n|---------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| Reusability | Modularization enables opportunities for code sharing and building multiple apps from the same foundation. Modules are effectively building blocks. Apps should be a sum of their features where the features are organized as separate modules. The functionality that a certain module provides may or may not be enabled in a particular app. For example, a `:feature:news` can be a part of the full version flavor and wear app but not part of the demo version flavor. |\n| Strict visibility control | Modules enable you to easily control what you expose to other parts of your codebase. You can mark everything but your public interface as `internal` or `private` to prevent it from being used outside the module. |\n| Customizable delivery | [Play Feature Delivery](/guide/playcore/feature-delivery) uses the advanced capabilities of app bundles, allowing you to deliver certain features of your app conditionally or on demand. |\n\nThe benefits of modularization are only achievable with a modularized codebase.\nThe following benefits might be achieved with other techniques but\nmodularization can help you enforce them even more.\n\n| Benefit | Summary |\n|---------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| Scalability | In a tightly coupled codebase a single change can trigger a cascade of alterations in seemingly unrelated parts of code. A properly modularized project will embrace the [separation of concerns](https://en.wikipedia.org/wiki/Separation_of_concerns) principle and therefore limit the coupling. This empowers the contributors through greater autonomy. |\n| Ownership | In addition to enabling autonomy, modules can also be used to enforce accountability. A module can have a dedicated owner who is responsible for maintaining the code, fixing bugs, adding tests, and reviewing changes. |\n| Encapsulation | Encapsulation means that each part of your code should have the smallest possible amount of knowledge about other parts. Isolated code is easier to read and understand. |\n| Testability | Testability characterizes how easy it is to [test](/training/testing) your code. A testable codebase is one where components can be easily tested in isolation. |\n| Build time | Some Gradle functionalities such as incremental build, build cache or parallel build, can leverage modularity to [improve build performance](/studio/build/optimize-your-build). |\n\nCommon pitfalls\n---------------\n\nThe granularity of your codebase is the extent to which it is composed of\nmodules. A more granular codebase has more, smaller modules. When designing a\nmodularized codebase, you should decide on a level of granularity. To do so,\ntake into account the size of your codebase and its relative complexity. Going\ntoo fine-grained will make the overhead a burden, and going too coarse will\nlessen the benefits of modularization.\n\nSome common pitfalls are as follows:\n\n- **Too fine-grained** : Every module brings a certain amount of overhead in the form of increased build complexity and [boilerplate code](https://en.wikipedia.org/wiki/Boilerplate_code). A complex build configuration makes it difficult to [keep configurations consistent](/topic/modularization/patterns#consistent-configuration) across modules. Too much boilerplate code results in a cumbersome codebase that is difficult to maintain. If overhead counteracts scalability improvements, you should consider consolidating some modules.\n- **Too coarse-grained**: Conversely, if your modules are growing too large you might end up with yet another monolith and miss the benefits that modularity has to offer. For example, in a small project it's ok to put the data layer inside a single module. But as it grows, it might be necessary to separate repositories and data sources into standalone modules.\n- **Too complex**: It doesn't always make sense to modularize your project. A dominating factor is the size of the codebase. If you don't expect your project to grow beyond a certain threshold, the scalability and build time gains won't apply.\n\nIs modularization the right technique for me?\n---------------------------------------------\n\nIf you need the benefits of reusability, strict visibility control or to use the\n[Play Feature Delivery](/guide/playcore/feature-delivery), then modularization is a necessity for you. If you\ndon't, but still want to benefit from improved scalability, ownership,\nencapsulation, or build times, then modularization is something worth\nconsidering.\n\nSamples\n-------\n\n- [Now in Android](https://github.com/android/nowinandroid) - fully functional Android app featuring modularization.\n- [Multi module architecture sample](https://github.com/android/architecture-samples/tree/multimodule)"]]