DDD

DDD는 복잡한 도메인을 명확히 표현하고, 비즈니스 규칙을 코드 구조의 중심에 두는 설계 방식이다. 구성은 크게 Presentation → Application → Domain → Infrastructure 계층으로 나뉜다.

DDD의 중요 개념

  • 도메인(Domain): 소프트웨어가 해결하려는 비즈니스 영역이나 문제 공간.
  • 유비쿼터스 언어(Ubiquitous Language): 팀 내 모든 구성원이 공통으로 사용하는 언어로, 도메인 모델과 소통을 일관되게 유지.
  • 바운디드 컨텍스트(Bounded Context): 도메인을 여러 개의 독립된 컨텍스트로 분리하여 복잡성을 관리.
  • 애그리거트(Aggregate): 도메인 모델 내에서 일관성을 유지해야 하는 객체들의 집합.
  • 루트 애그리거트(Root Aggregate): 애그리거트의 진입점이 되는 핵심 엔티티.
  • 벨류 오브젝트(Value Object): 식별자가 필요 없는 객체로, 속성만으로 식별됨.
  • 엔티티(Entity): 고유한 식별자를 가지며, 지속적인 생명주기를 가진 도메인 객체.

1. Presentation Layer (UI 계층)

역할

  • 사용자의 입력을 받고 결과를 반환
  • Application Service를 호출하여 처리 흐름을 시작함

구성 요소

Controller

  • HTTP 요청/응답 처리
  • DTO 매핑
  • 비즈니스 로직 없음

DTO (Request / Response)

  • 계층 간 데이터 전달 객체
  • 검증 및 단순 변환만 수행
  • 도메인 지식 포함 X

2. Application Layer (애플리케이션 계층)

역할

  • 유즈케이스(Use Case) 실행
  • 도메인 객체를 조립하고 트랜잭션 경계를 관리
  • 도메인 규칙은 포함하지 않음 (흐름만 제어)

구성 요소

Application Service

  • Controller → Application Service → Domain 객체 호출 흐름 구성
  • 예: 주문 생성, 사용자 등록 프로세스 처리

Command / Query (옵션, CQRS 기반)

  • Command: 상태 변경
  • Query: 데이터 조회

3. Domain Layer (도메인 계층)

역할

DDD의 핵심. 비즈니스 규칙, 모델, 정책을 모두 포함하며 어떤 기술에도 의존하지 않아야 함.

구성 요소

Entity

  • 고유 ID를 가지고 상태 + 행동을 가진 객체
  • 예: Order, User

Value Object

  • 식별자 없음, 속성 기반 비교
  • 불변성 유지
  • 예: Money, Address

Aggregate & Aggregate Root

  • 불변성을 유지해야 하는 객체 그룹
  • Root 외부에서는 내부 객체에 직접 접근 불가

Domain Service

  • 특정 Entity에 속하지 않는 도메인 규칙 처리
  • 무상태(stateless)

Repository Interface

  • 도메인 계층에서 영속성 기술을 추상화한 인터페이스 선언

Domain Event

  • 도메인 내 의미 있는 사건 표현 (예: 주문 생성됨)

4. Infrastructure Layer (인프라 계층)

역할

  • 기술적 구현부 (DB, Network, File, 외부 API 등)

구성 요소

Repository 구현체

  • Repository 인터페이스의 실제 구현
  • 예: JPA 기반 구현

외부 API 연동

  • RestTemplate, WebClient 등 호출

설정 / 구성 요소

  • ORM 설정
  • 메시지 브로커, Redis, Kafka 등

전체 구조 요약 (디렉토리 예시)

presentation/
 └─ controller/
 └─ dto/
 
application/
 └─ service/
 └─ command/
 └─ query/
 
domain/
 └─ entity/
 └─ vo/
 └─ service/
 └─ repository/
 └─ event/
 └─ aggregate/
 
infrastructure/
 └─ repository/
 └─ external/
 └─ config/

DDD vs MVC 구조 비교

구조 차이 개요 표

구분MVCDDD
목적빠른 개발, 화면 중심도메인 복잡도 관리, 비즈니스 중심
주요 관심사UI 흐름 제어도메인 모델링, 규칙 중심
계층 구성Model, View, ControllerPresentation, Application, Domain, Infrastructure
Model 역할DB 매핑 + 비즈니스 로직 혼재Domain Entity/VO/Service로 역할 분리
서비스 레이어필수 아님Application Service + Domain Service로 명확 분리
DTO 필요성경우에 따라 생략 가능필수적 (계층 간 책임 분리)
일관성상대적으로 느슨함Aggregate 중심 강한 일관성

DDD의 장점과 단점

장점

  1. 복잡한 도메인 표현에 강함

    • 비즈니스 규칙이 코드 구조에 반영됨
    • 유지보수 시 규칙 이해가 쉬움
  2. 변경에 강한 구조

    • UI, DB 기술이 바뀌어도 Domain은 영향받지 않음
    • 확장성 ↑
  3. 팀 간 협업 향상

    • 도메인 언어(Ubiquitous Language)를 통해 동일 용어 사용 가능
  4. 테스트 용이

    • Domain이 순수 로직만 담고 있기 때문에 단위 테스트 쉬움

단점

  1. 설계 비용이 높음

    • 모델링 회의, Aggregate 설계, 이벤트 설계 등
    • 소규모 프로젝트에는 과할 수 있음
  2. 학습 난이도

    • DDD 개념(VO, Aggregate, Event 등)을 모두 이해해야 효과적
  3. 계층 분리로 초기 개발 속도 저하

    • 파일/클래스 갯수 증가
    • 단순 CRUD에서는 비효율적일 수 있음

MVC 대비 DDD를 선택해야 할 시점

DDD가 적합한 경우

  • 도메인 규칙이 복잡하거나 자주 바뀜
  • 금융, 결제, 유통, 정책 기반 시스템
  • 장기 운영을 전제로 한 서비스

MVC 또는 단순 구조가 적합한 경우

  • 단순 CRUD 위주의 시스템
  • MVP 단계, 빠른 출시가 최우선
  • 도메인 규칙이 거의 없음