멀티 모듈이란?
하나의 시스템이나 프로젝트를 여러 개의 독립적인 모듈로 분리하여 구성하는 방식이다. 모듈화된 구조는 비슷한 기능을 가진 모듈을 다른 프로젝트에서도 사용함으로써 코드의 재사용성을 높여준다는 장점이 있다.
독립적인 공통 코드란, StringUtils, DateUtils와 같이 다른 시스템에도 사용될 수 있는 코드를 뜻하며, 추후 재사용성을 고려해 이를 기준으로 모듈을 분리한다.
상황에 따라 존재하지 않은 수도 있으며, 라이브러리 형태 jar로 패키징되어 저장소에 배포되고 의존할 수 있다.
시스템에 종속적인 코드는 두가지 영역으로 나눌 수 있다.
수준을 엄밀하게 정의하자면 입력과 출력까지의 거리이다.
시스템의 입력과 출력 모두로부터 멀리 위치할수록 고수준 정책에 해당되며, 따라서 도메인 영역은 고수준 영역, 인프라 영역은 저수준 영역에 해당된다.
이 둘은 변경이 요구되는 시점이 다르기 때문에 최대한 독립시켜주는 것이 좋다.
*도메인 모듈에는 entity, enum 등 포함되지만 절대 유스케이스는 포함 시키지 않는다.
API를 제공하거나, 통계 또는 일괄처리를 위한 배치 작업, SSR기반 웹페이지 제공 기능 등 각 기능마다 필요로 하는 의존성이 다르기 때문에 모듈로 나누는 것이 좋다.
SOLID원칙 중 SRP(Single Responsibility Principle) 단일 책임 원칙이란 "단일 모듈은 변경의 이유가 하나, 오직 하나 뿐이어야 한다." 라는 의미이다.
동일한 기능이라도 서로 다른 액터라면, 추후 액터의 요구가 점점 달라질 수 있기 때문에 액터를 기준으로 모듈을 나누는 것이 좋다.
유스케이스를 공통 코드로 뺀다면 사이드 이펙트가 발생하기 쉽고, 예외 케이스를 위한 분기 처리도 들어가면서 많은 문제가 발생된다.
코드가 비슷하다고 해서 모두 중복은 아니다. 서로 다른 액터를 처리하고 있다면 진짜 중복이 아닌 우발적 중복이라 볼 수 있다.
특정 기능이 불필요한 모듈에서까지 연결이 되어버리기 때문에 인프라 구성을 제어할 수 없게 된다. 또한 어떤 인프라 구성들이 존재하는지 명시적으로 파악하기가 어렵기 때문에 spring에서 제공하는 ImportSelector를 이용해 인프라 구성에 대한 제어권을 획득하자.
모든 모듈이 의존하기 때문에 변경이 모든 모듈에 영향을 끼칠 수 있다.
공통 모듈을 관리하기 위한 방법
결정 사항을 미루라는 조언은 애플리케이션 개발에도 일맥상통하다.
프로젝트가 계속 진화함에 따라 최적인 구조가 달라질 수 있고, 어떤 구조가 더욱 적합한지 현재로써 판단하기 힘들기 때문이다.
처음 접하는 팀원에게 인지 부하를 줄 수 있다. 최대한 단순하고 직관적이게 가져가는 것이 좋다고 생각한다.
참고 자료