해당 프로젝트 관련 글
[Android] 자동 로그인 with DataStore(Kotlin)
[Android] Retrofit으로 에러 메시지 처리하기
[Android] - 레이어 분리 [멀티 모듈 적용기(1)]
이전 글에서는 멀티 모듈 적용을 위해서 의존성 방향이 정리되지 않은 Domain, Data, Presentation의 계층을 완전하게 분리했습니다.
이번 글에서는 분리한 계층들을 하나의 App 모듈에서 여러 개의 모듈로 분리해 보는 과정과 느꼈던 점에 대해서 적어볼까 합니다.
그전에 모듈에 대해서 알아볼까 합니다.
모듈이란?
- 모듈은 소스 파일 및 빌드 설정으로 구성된 모음이며, 이를 통해 프로젝트를 별개의 기능 단위로 분할할 수 있습니다.
- 프로젝트에는 하나 이상의 모듈이 포함될 수 있습니다.
- 하나의 모듈이 다른 모듈을 종속적으로 사용할 수 있습니다.
- 모듈의 대표적인 예로는 자동으로 생성되는 app 모듈이 있습니다.
그렇다면 왜 하나의 모듈을 귀찮게 여러 개로 분리하는 과정을 겪을까요?
멀티 모듈의 장점
관심사 분리가 가능하다.
- 기존의 단일 모듈 방식에서는 실수로 의존성 규칙을 위반할 수 있지만, 멀티 모듈 방식을 사용하면 build.gradle 파일에서 의존성을 추가하지 않는다면 다른 모듈의 코드를 사용할 수 없고, 자연스레 의존성 규칙을 쉽게 관리할 수 있습니다.
즉 클린아키텍처에서의 Domain 모듈은 다른 모듈을 종속적으로 사용하고 있지 않는 것이 바람직합니다.
따라서 Data, Presentation의 코드를 사용하는 것이 옳지 않는데, 멀티 모듈 구조를 사용할 경우 분리가 가능합니다.
빌드 시간 감소를 기대할 수 있다.
사실 이 부분에 대해서는 크게 와닿은 부분은 없습니다. 현업자도 아니고, 보통의 신입 개발자분들이 하는 프로젝트에서 이러한 빌드 감소를 체감할만한 규모로 개발하기가 쉽지 않다고 생각합니다.
하지만 현업에서는 서비스가 큰 프로젝트에서는 100개의 모듈을 사용하는 프로젝트도 있다고 합니다.
이러한 규모에서 하나의 모듈을 계속해서 빌드하는 시간보다는 변경된 모듈만 빌드해서 빌드 시간을 감소하는 것에 체감이 매우 크다고 합니다. 하지만 너무 많은 모듈이 있을 경우 관심사 분리를 잘하더라도, 복잡해지는 것은 어쩔 수 없는 것 같습니다.
코드 재사용성이 높아진다.
사실 클린 아키텍처로 모듈을 분리할 경우는 코드의 재사용성이 크게 높아지는 건가?라는 생각이 들곤 합니다.
하지만 최근 안드로이드에서는 클린 아키텍처의 정의를 조금 다르게 하고, 기능 별로 모듈 분리를 하는 추세라 그러한 구조인 경우 코드 재사용성이 상당히 높을 것이라고 생각합니다. 해당 모듈에 대한 의존성만 추가해서 사용하면 되기 때문에 반복되는 코드를 확실히 줄일 수 있다고 생각합니다.
안드로이드 클린 아키텍처는 의존성 방향이 UI -> Domain -> Data로 클린아키텍처와 다릅니다.
아마 NowInAndroid에 가면 이 구조를 적용해 기능별로 모듈을 적용한 레포지토리가 있고, 그것을 참고해서 하는 것도 좋은 방법이라고 생각합니다.
그 외 모듈 단위 테스트를 진행할 수 있다는 장점이 있지만, 저는 테스트 코드를 작성하지 않아서 느끼지 못했습니다ㅠㅠ
안드로이드 스튜디오에서 모듈을 생성할 경우 File -> New Moudle 탭으로 이동해야 합니다.
여기서 주목해야 할 점은 만들 수 있는 모듈의 템플릿이 굉장히 많다는 점입니다.
여기서 주로 사용되는 템플릿은 Phone & Tablet, Android Library, Java or Kotlin Library입니다.
각 템플릿에 대응되는 모듈은 다음과 각각 다음과 같습니다.
- Phone & Tablet -> App 모듈
- Android Library -> Data, Presentation
- Java or Kotlin Library -> Domain
모듈화의 핵심은 각 모듈에게 필요한 라이브러리만을 사용하게 하는 것이고, LiveData보다 Flow 사용이 선호되는 이유도
Domain Layer에서 LiveData를 이용해 버리면 Android 의존성을 갖기 때문입니다.
지금부터는 클린 아키텍처의 설계에 따라 의존 방향을 잘 생각해서 모듈 분리를 해볼 것입니다.
- Presentation, Data 모듈은 Domain에 의존
- App 모듈은 3개 모듈 모두 의존 (의존성 주입 때문)
모듈 분리를 하기 전에 알아야 할 것이 또 있습니다.
Version Catalog라는 친구입니다.
Version Catalog
최근 안드로이드 프로젝트를 새로 시작하면 build.gradle의 문법이 바뀐 것을 확인할 수 있는데, 그것이 Version Catalog 방식입니다.
안드로이드 공식 문서에 따르면 버전 카탈로그를 사용하면 확장 가능한 방식으로 종속 항목 및 플러그인을 추가하고 유지할 수 있다고 합니다.
코드로 살펴보면 더 쉬운데요,
implementation("com.google.dagger:hilt-android:2.44")
implementation(libs.hilt.android)
기존의 방식보다 뭐가 더 좋길래 바뀐 것일까요? 그리고 멀티 모듈을 적용한다면 Version Catalog가 각광받을까요?
장점
- 하나의 파일로 여러 프로젝트 및 모듈의 버전 관리를 통합할 수 있습니다.
- 특히 멀티 모듈을 적용함에 있어 같은 의존성을 모듈마다 추가해 주는 경우가 있는데, 이 경우 하나의 파일에서 버전을 쉽게 관리할 수 있습니다.
- 예를 들어 핵심 라이브러리의 버전이 바뀔 경우 모듈마다 이를 적용해줘야 하는데, Version Catalog를 적용하면 매우 쉽게 관리할 수 있는 장점이 있습니다.
- 함께 사용되는 의존성들을 bundle로 묶어 가독성 좋게 사용할 수 있습니다.
- IDE 상에서 Catalog마다 자동 완성 기능 등 편리한 요소를 지원합니다.
Version Catalog를 적용하기 위해선 gradle 폴더 아래에 toml 파일을 생성해줘야 합니다.
toml 파일은 다음과 같이 구성됩니다.
- versions : 라이브러리 버전에 대한 변수명과 같은 값을 정의
- libraries : 라이브러리 정의
- plugins : 플러그인 정의
- bundles : 연관 있는 라이브러리끼리 묶어 그룹핑
혹시 version catalog가 아닌 이전 방식을 택하고 있다면 NowInAndroid의 libs.version.toml 파일을 참고해 변경하시는 것을 추천합니다. 해당 파일은 compose를 기반으로 설명하고 있지만, 보시면 조금 감이 오실 거라 생각 듭니다.
이렇게 만든 toml 파일을 gradle에 적용해 보면 다음과 같습니다.
위 사진은 Data Moudle에 해당되는데, bundle로 여러 라이브러리를 한꺼번에 그리고 명시적으로 표현해 깔끔해진 것을 확인할 수 있습니다.
만약 gradle 버전이 7.4 이하라면 toml 파일의 경로를 명시해줘야 하는데, settings.gradle.kts 파일에 다음과 같은 코드를 추가해 주세요
enableFeaturePreview("VERSION_CATALOGS")
dependencyResolutionManagement {
versionCatalogs {
create("fileName") {
from(files("fileName.version.toml"))
}
}
}
기존의 구조에서 version catalog로 마이그레이션 하는 과정에서 굉장히 많은 오류가 있을 것이라고 생각이 듭니다.
대부분의 오류가 중복된 라이브러리가 포함되어 생긴 오류였고, 그러한 경우 라이브러리에 대한 주입을 잘 확인하시는 것을 추천드립니다 ㅎ
멀티 모듈을 적용하고, version catalog를 도입해 보면서 느꼈던 점은 해당 방식이 편하다! 꼭 해보자!라는 감정보다는
기존의 설계 방식을 변경하는 것이 매우 매우 힘들고, 어렵다라는 것을 느꼈습니다.
단일 모듈에서 여러 계층의 코드를 깔끔하게 분리를 하고, 또 그 분리된 패키지들을 모듈로 적용하는 것에 꼬박 하루를 넘게 사용한 것 같습니다.
아직도 클린 아키텍처 구조를 반드시 따르고, 멀티 모듈을 적용해야 하냐?라고 하면 선뜻 대답하기 힘든 것 같습니다.(제 수준에서는요)
하지만 현업에서도 멀티 모듈을 적용하는 것이 당연하고, 이번 경험을 통해 코드를 수정하는 작업이 굉장히 힘든 것을 느꼈습니다.
또 안드로이드의 클린 아키텍처이냐, 로버트 마틴의 클린 아키텍처이냐에 대한 의견은 사실 자기가 편한 대로 하는 것이 정답이 아닐까..라는 생각을 합니다.
저 같은 경우 이미 진행 중인 프로젝트에서 클린 아키텍처를 적용하는데 있어서 분리하기 힘들다고 판단된 것이 안드로이드 클린 아키텍쳐여서 클린 아키텍쳐를 선택한 감이 없지 않아 있습니다.
안드로이드 클린 아키텍처는 Feature 중심 모듈화이고, Feature 별 사용되는 drawable이 분리돼있는 것을 보고 경악을 했습니다ㅋㅋ
해당 글은 제가 공부를 한 개인적인 의견이기 때문에 정답이 아닙니다. 그 점 참고해 주세요!
참고
https://brunch.co.kr/@purpledev/43
https://everyday-develop-myself.tistory.com/309
https://brunch.co.kr/@purpledev/46
'Skils > Android' 카테고리의 다른 글
[Android] - 외부 라이브러리 없이 동영상 편집 구현하기 (0) | 2024.08.24 |
---|---|
[Android] - 동영상에 대한 썸네일 리스트 반환하기 (0) | 2024.08.10 |
[Android] - 레이어 분리 [멀티 모듈 적용기(1)] (0) | 2024.07.07 |
[Android] 커스텀 컨트롤러 구현 및 동영상 재생 관리 (2) | 2024.06.23 |
[Android] 비디오 타임라인 이벤트 처리 (0) | 2024.06.23 |