Article/개발 꿀팁
패키지 구조 선택 방법
조금씩 차근차근
2025. 4. 27. 22:28
여태까지 수많은 강의와 책을 봤지만, 이런 내용은 기본적이라고 취급하는지 뚜렷한 기준을 찾기 어려웠다.
따라서 직접 정리해보았다.
패키지의 구성요소 분류
- 설명하기 전에, 다음 세가지 요소를 설명하도록 하겠다.
모듈
- 비즈니스 도메인 내에서 정의하는 하나의 기능 단위를 의미한다.
- 예시
- order
- member
- product
레이어
- 아키텍쳐에서 추구하는 계층 구조를 의미한다.
- 예시
- domain: 비즈니스 로직을 담당하는 레이어. 도메인 모델과 도메인 서비스, 도메인 이벤트가 여기 속한다.
- application: 비즈니스 로직을 이용한 UseCase 를 담당하는 레이어. 대표적으로 application service, QueryRepository 계열이 있다.
- interface: Use Case를 직접 호출하는 레이어. 대표적으로 job scheduler, web controller가 있다.
- infrastructure: 인프라 관련된 구성요소들이 들어가는 레이어. DB나 캐시 스토리지, 메시지 브로커, 외부 API 등이 이곳에 속해 있다.
구성요소
- 실제 레이어 내에 존재할 수 있는 구성요소를 의미한다.
- 예시
- model(domain)
- exception(domain)
- EventHandler(application, interface)
- service(application, domain)
- controller(interface)
- JPA(infra)
- JDBC(infra)
우리는 패키지 구조를 선택할 때, 최대한 상위 패키지에서 하위 패키지로만 의존이 가능하도록 선택하기를 희망한다. 해당 기준에서 봤을 때, 패키지 구조는 다음과 같이 분류할 수 있다.
- 모듈 -> 레이어 -> 구성요소
- 레이어 -> 모듈 -> 구성요소
- 레이어 -> 구성요소 -> 모듈
일반적으로 레이어 별로 구성요소가 달라지기 때문에, 레이어 -> 구성요소는 고정해둔 상태에서, 모듈의 위치에 따른 패키지 구조를 평가하도록 하겠다.
모듈 -> 레이어 -> 구성요소
- com.foo.order.domain.model
- 주로 DDD, Hexagonal Architecture 관점에서 이루어진다.
- 모듈 간 의존을 엄격하게 분리하는 구현을 지향한다.
장점
- domain → application → infra 방향만 허용 등 계층 규칙을 모듈 내부에서 쉽게 검사할 수 있다.
- 멀티모듈로 전환이 용이하다.
- 의존성이 엄격히 관리되기 때문에, 의존성 및 테스트 코드 작성이 용이해진다.
단점
- 모듈 간 의존을 지양하기 때문에, 생산성이 떨어지게 된다.
레이어 -> 모듈 -> 구성요소
- com.foo.domain.order.model
- 주로 Layered Architecture, clean Architecture 관점에서 이루어진다.
- 같은 레이어 내 모듈 간 의존이 어느정도 허용되는 설계를 목표로 한다.
장점
- 팀원이 해당 패키지 구조를 한눈에 이해할 수 있게 만들어준다.
- 도메인 객체가 뭐뭐가 있지?
- 모듈 간 의존을 어느정도 허용하기 때문에, 생산성이 Hexagonal과 같은 엄격한 아키텍처에 비해 좀 더 높다.
단점
- 멀티모듈로 전환 시 불편하다.
- 모듈 간 의존이 어느정도 허용돼서 단위 테스트 코드 작성이 까다로워지기 때문에, 도메인 객체를 제외하곤 주로 E2E 테스트만으로 테스트를 수행하게 된다.
- 못한다는 건 아니다. 생산성이 떨어진다는 뜻이다.
레이어 -> 구성요소 -> 모듈
- com.foo.domain.model.order
- 현재 내가 학습하고있는 DDD 학습용 프로젝트인 dddsample-core 패키지의 구조이다.
- 해당 프로젝트는 에릭 에반스의 “도메인 주도 설계”에 등장하는 프로젝트를 실제로 구현한 프로젝트로, DDD 학습에 용이하다.
장점
- DDD의 핵심 구성요소를 파악하기 좋다.
단점
- 실무에서는 써먹기 힘들다. 의존이 어느정도 허용되는지를 패키지 구조로 파악하기 어렵다.
- 실제로 이 블로그 글에서도, 중요한 DDD 컨셉을 강조하기 위해, 도메인 패키지 내 모듈을 두는 것을 선택했다고 말하고 있다.
참고 자료