MSA
25.03.13 도메인 주도 설계 ( DDD )의 계층구조
ddong-kka
2025. 3. 13. 01:07
개요
DDD의 계층구조는 내가 알고있던 계층구조와는 조금 다른 개념이라 정리해본다.
DDD( Domain-Driven Design )에서의 계층 구조 ( Layered Architecture )
DDD에서 계층형 아키텍처 ( Layered Architecture )는 애플리케이션을 여러 개의 독립적인 계층으로 나누어 각 계층이
특정한 역할을 담당하도록 하는 설계 방식입니다. 이러한 계층 구조를 적용하면 관심사의 분리 (Separation of Concerns)
를 실현할 수 있어 유지보수성과 확장성이 좋아집니다.
DDD의 계층 구조
DDD에서는 일반적으로 다음과 같은 4가지 계층을 사용한다.
- 사용자 인터페이스 ( User Interface, UI ) 또는 프레젠테이션 ( Presentation ) 계층
- 애플리케이션 ( Application ) 계층
- 도메인 ( Domain ) 계층
- 인프라스트럭처 ( Infrastructure ) 계층
이러한 계층을 적용하면 도메인 로직을 인프라와 UI로부터 독립적으로 유지할 수 있으며, 유연한 변경과 확장이 가능하다.
각 계층의 역할
사용자 인터페이스 ( User Interface, Presentation ) 계층
- 역할 : 사용자와 애플리케이션 간의 인터페이스를 담당한다.
- 사용자 요청에 대해 해석하는 응답하는 일을 책임지는 계층
- 예시 : RestContoller , 요청 예외처리 핸들러
- 사용자에게 UI 제공를 제공하거나 클라이언트에 응답을 다시 보내는 역할을 하는 모든 클래스가 포함된다.
- Client로부터 request를 받고 response를 return하는 API 정의
애플리케이션 ( Application ) 계층
- 역할 : 도메인 계층을 호출하고 저장하는 역할을 한다. 주요 비즈니스 로직은 도메인 계층에 위임한다.
- 비즈니스 로직을 정의하고 정상적으로 수행될 수 있도록 도메인 계층과 인프라스트럭쳐 계층을 연결해주는 역할을 하는 계층
- 예시 : Serivce
- 많은 정보를 가지고있지 않게 유지하는것이 중요
- 실질적인 데이터의 상태 변화 등의 처리는 도메인 계층에서 진행할 수 있도록 위임하는 것이 중요
- 포함하는 기능
- 트랜잭션의 단위
- DTO 변환
- 엔티티 조회/ 저장
- 요약 : Entity를 찾고 ( Repository ), 변경 내용을 저장하는 기능 ( Persistence )을 호출한다.
도메인 ( Domain ) 계층
- 역할 : 핵심 비즈니스 로직을 포함하며, 다른 계층에 의존하지 않도록 설계한다
- 비즈니스 규칙, 정보에 대한 실질적인 도메인에 대한 정보를 가지고 있으며 이 모든것을 책임지는 계층이다.
- 예시 : Entity
- Entity를 활용하여 도메인 로직이 실행되며, 업무 상황을 반영하여 상태를 제어하는 역할에 집중하는 계층
- 애그리게이트(Aggregate)와 애그리게이트 루트(Aggregate Root)를 관리
인프라스트럭처 ( Infrastructure ) 계층
- 역할 : 데이터베이스, 메시징 시스템, 외부 API 호출 등의 기술적 요소를 처리합니다.
- 외부와의 통신 ( DB, 메시징 시스템 등)을 담당하는 계층이다.
- 예시 :
- 영속성 관리 ( JPA, Redis, MongoDB 등 )
- 이벤트 발행 ( RabbitMQ, Kafka 등)
- 외부 API 연동 ( FeginClient, RestRemplate 등 )
- 해당 계층에서 얻어온 정보를 응용 계층 또는 도메인 계층에 전달하는 것이 주 역할이다.
디렉토리 구조 예시
project-root/
│── account-service/ # 사용자 계정 서비스 (Microservice)
│ ├── src/main/java/com/example/account/
│ │ ├── application/ # 응용 계층 (서비스, 유스케이스)
│ │ │ ├── service/ # 비즈니스 로직 (도메인 서비스)
│ │ │ ├── dto/ # 요청/응답 DTO
│ │ │ ├── exception/ # 예외 처리 클래스
│ │ │ ├── event/ # 이벤트 핸들링 (RabbitMQ, Kafka)
│ │ │ │ ├── producer/ # 이벤트 발행 (KafkaProducer, RabbitMQ Publisher)
│ │ │ │ ├── consumer/ # 이벤트 소비 (KafkaListener, RabbitMQ Listener)
│ │ ├── domain/ # 도메인 계층
│ │ │ ├── model/ # 핵심 도메인 엔티티, VO
│ │ │ ├── repository/ # 도메인 리포지토리 인터페이스
│ │ ├── infrastructure/ # 인프라 계층
│ │ │ ├── repository/ # 데이터 저장소 구현 (JPA, QueryDSL)
│ │ │ ├── messaging/ # 메시징 관련 설정 및 구현 (Kafka, RabbitMQ)
│ │ │ ├── client/ # 외부 API 연동 (FeignClient 등)
│ │ │ ├── config/ # 설정 관련 클래스 (DB, Security, 메시징 설정)
│ │ ├── interface/ # 인터페이스 계층 (입출력)
│ │ │ ├── controller/ # REST 컨트롤러
│ │ │ ├── handler/ # 요청 예외 처리 핸들러
│ │ │ ├── consumer/ # WebSocket, gRPC 등 추가 인터페이스
│ ├── src/test/java/com/example/account/ # 테스트 코드
│ ├── build.gradle # Gradle 설정 파일
│ ├── Dockerfile # Docker 빌드 파일
│ ├── application.yml # 애플리케이션 설정 파일
│ ├── kafka-docker-compose.yml # Kafka 및 Zookeeper 설정 파일
│ ├── rabbitmq-docker-compose.yml # RabbitMQ 설정 파일