도메인 주도 설계의 모듈 구성(패키지 구성)

2022. 1. 10. 16:20도메인주도설계

패키지 구성을 설계하는 것에는 한 가지 정답만 있는 것은 아니지만 이 번 시간에는 도메인 주도 설계에서 일반적으로 사용되는 패키지 구성을 소개하고자 합니다.

규칙1. 아키텍처의 각 영역은 별도 패키지에 위치합니다.

아키텍처 영역과 매핑된 패키지

  • ui: 표현 영역
  • application: 응용 영역
  • domain: 도메인 영역
  • infrastructure: 인프라 영역

규칙2. 도메인이 크면 하위 도메인별로 모듈을 나눕니다.

하위 도메인별 패키징
도메인 모듈은 애그리거트 기준으로 다시 패키징

모듈 구성 예시)

com.myshop

    ㄴ order

    ㄴ member

    ㄴ catalog

        ㄴ ui

        ㄴ application

        ㄴ infrastructure

        ㄴ domain

            ㄴ product

            ㄴ category

도메인이 복잡하다면 도메인 모델과 도메인 서비스를 다음과 같이 별도 패키지에 위치시킬 수도 있습니다.

com.myshop.order.domain.order: 애그리거트 위치

com.myshop.order.domain.service: 도메인 서비스 위치

모듈 구조를 얼마나 세분화해야 하는지에 대해 정해진 규칙은 없습니다.
단지, 한 패키지에 너무 많은 파일이 몰려서 코드를 찾을 때 불편한 정도만 아니면 됩니다.
개인적으로는 한 패키지에 가능하면 10개 미만으로 파일 개수를 유지하려고 노력합니다.
이 개수가 넘어가면 모듈을 분리하는 시도를 해봅니다.

기존)

com.myshop

    ㄴ controller

    ㄴ service

    ㄴ mapper

    ㄴ factory

    ㄴ handler

    ㄴ validator

......

 

추천)

com.myshop

    ㄴ ui

        ㄴ contorller

        ㄴ validator

    ㄴ application

        ㄴ service

        ㄴ validator

    ㄴ domain

    ㄴ infrastructure

 

개인적으로 com.myshop.controller 나 com.myshop.service 와 같이 객체의 유형별로 처음부터 패키지를 나누는 것보다, 아키텍처 영역을 기준으로 먼저 패키지를 나누고 필요시, 그 아래에 유형별로 패키지를 나누는게 더 유연하고 일관적으로 프로젝트 전체 패키지를 구성하는데 좋다고 생각합니다.

저렇게 구성할 경우, 가장 큰 장점은 패키지 의존 방향을 추측할 수 있다는 것 입니다.

물론 계층화 아키텍처에 대해서 아는 개발자여야 패키지 의존 방향을 추측할 수 있습니다.

의존 방향을 추측할 수 있다는 것은, 변경사항이 일어났을 때, 해당 객체가 어떤 객체에 영향을 줄지 그 영향도를 추측할 수 있다는 말이 됩니다. 

계층화 아키텍처에 의해서 표현, 응용, 도메인, 인프라 상위에서 하위로 의존하며 DIP를 적용해 저수준 모듈이 고수준 모듈을 의존한다는 것을 알고 있기에,

응용 계층을 수정하면 표현 계층이 수정될 수 있다는 것을 개발자는 추측할 수 있습니다.

 

또한 변경에 의한 영향 범위를 추측할 수 있습니다.

만약, service에서 수행하는 validate 작업이 커져서 따로 validator 객체를 뽑아 냈다면, 기존 패키지 구성일 경우 validator 패키지를 만들 것입니다. 그리고 그 패키지에는 어쩌면 controller에서 수행하는 validate, 도메인 영역에서 수행하는 validate 모두 포함될 수 있습니다. 즉, 의존방향을 추측할 수 없습니다. validator가 수정되면 또 어떤 패키지에 영향을 줄지 파악하기 힘듭니다.

(물론 기술적으로 의존방향을 제한하는 방법은 없습니다. 개발자들이 의식적으로 제한해야합니다.)

아키텍처 개념을 패키지화하면 validator가 수정됐을 때 해당 validator가 영향을 줄 수 있는 범위를 제한할 수 있습니다.

 

결론, 아키텍처 영역으로 먼저 패키지를 나누면 의존 방향을 추측할 수 있고 이로 인해 로직 변경시 영향도 추측이 가능합니다.