멀티 모듈이 무엇이고, 왜 사용할까?
1. 멀티 모듈이란?
Java에서 모듈이란 패키지의 한 단계 위의 집합체이며, 서로 밀접하게 연관된 패키지들과 리소스들의 그룹을 의미한다. 각 모듈은 독립적으로 개발, 빌드, 테스트, 배포가 가능하다.
멀티 모듈 프로젝트는 상호 연결된 여러 개의 모듈로 구성된 프로젝트로, 각 모듈이 서비스의 구성요소로서 동작한다.
2. 멀티 모듈 프로젝트 - 단일 모듈 멀티 프로젝트 vs 멀티 모듈 싱글 프로젝트
회원 시스템을 예시로 들며 멀티 모듈 프로젝트에 대해 자세히 살펴보자.
회원 시스템을 개발하기 위해 아래와 같은 프로젝트가 필요하다.
- member-external-api: 고객 화면에서 호출하는 API 서버
- member-admin-api: 관리자 페이지에서 호출하는 API 서버
- member-batch: 주기적인 작업을 진행하는 서버
단일 모듈 멀티 프로젝트
단일 모듈 멀티 프로젝트에서는 각각의 프로젝트를 독립적인 프로젝트로 관리한다.
같은 도메인에 대해 별도의 프로젝트로 관리되기 때문에 중복되는 코드가 많이 발생하게 된다. (ex. 도메인 모델을 작성할 때에도 세 곳 모두 작성해주어야 한다.)
만약 이런 상황에서 수정 사항이 생긴다면, 3개 프로젝트를 모두 수정해주어야 한다. (by 복붙 ...) 개발자의 실수에 의해 처음에는 동일했던 코드가 서로 달라질 수 있고, 유지보수가 어려워진다.
이 뿐만 아니라 모든 프로젝트를 관리하기 위해 IDE 혹은 터미널을 프로젝트 갯수만큼 띄어놓아야 한다는 불편함도 있다.
멀티 모듈 싱글 프로젝트
멀티 모듈 싱글 프로젝트에서는 각각의 단일 프로젝트를 프로젝트 안의 '모듈'로서 가져 하나의 프로젝트에서 각각을 서브 프로젝트로서 관리한다.
하나의 프로젝트 안에 있기 때문에 코드를 공유할 수 있으며, 앞서 문제가 되었던 '중복 코드'를 줄일 수 있다.
관리 주체 또한 하나로 통합되었기 때문에 코드의 일관성을 유지하고, 유지보수의 용이성을 높이는 것 또한 가능해졌다.
싱글 모듈 싱글 프로젝트에서는 모든 코드가 함께 빌드되고 배포되는 반면, 멀티 모듈 싱글 프로젝트에서는 각각의 모듈은 독립적으로 빌드, 테스트, 배포하는 것도 가능하기 때문에 빌드와 배포의 측면에서도 이점을 가져갈 수 있다.
3. 멀티 모듈 프로젝트를 어떻게 구성할까?
멀티 모듈 프로젝트를 구성하는 방법에는 정답이 없다. 깃허브와 개발 블로그에서 멀티 모듈을 구성한 사례들과 조언들을 찾아본 결과, 바운디드 컨텍스트(Bounded Context)를 고려하며 멀티 모듈 프로젝트를 구성하는 것을 추천하는 것 같다.
바운디드 컨텍스트는 도메인 주도 설계(Domain Driven Development)에 등장하는 개념으로 특정한 의미를 가지는 범위, 경계, 맥락 등을 의미한다.
만약 쇼핑몰 서비스가 있을 때 해당 서비스를 회원, 결제, 주문 등의 요소로 구성되어 있으며 각각이 서로 다른 바운디드 컨텍스트에 속하는 것이다.
자세한 내용이 궁금하다면 DDD에 대해 공부해보자!
실전! 멀티 모듈 프로젝트 구조와 설계 에서는 아래와 같이 멀티 모듈 프로젝트를 구성하는 방법을 제시한다.
- boot (server) - 서버 모듈
- batch, admin, api 등이 포함되며 잦은 변화가 일어난다.
- infra - 연동 모듈
- 외부 서비스와 연동하는 모듈로 큰 변화가 일어날 가능성이 있다.
- cloud (system) - 클라우드 모듈
- AWS, GCP, Azure 등 클라우드 서비스 연동과 관련된 모듈이다.
- data (domain) - 데이터 모듈
- 프로젝트를 이루는 도메인들로 이루어진 모듈이다.
주변의 깃허브 프로젝트들을 살펴보았을 때는 api, admin, batch, core, common, infra, domain로 모듈로 분리하는 모습이 많이 보였다. 항상 이렇게 7개로 나뉘는 것은 아니고, api와 domain을 합치거나 admin이나 batch 모듈이 없는 경우도 있었다.
처음에 core와 common 모듈이 무슨 차이인지 잘 몰랐는데 아래와 같은 차이가 있는 것 같다.
- core: 다른 모듈에서 공유하는 비즈니스 로직을 포함
- common: 로깅, 예외 처리, 유틸리티와 같이 공통으로 사용하는 기능을 제공
멀티 모듈 프로젝트의 장점(응집성 강화, 결합도 낮춤)을 해치지 않기 위해 코드를 작성하며 core와 common 모듈이 비대칭적으로 커지지 않도록 주의하여야 한다.