ABOUT

성능과 운영 안정성을 함께 끌어올리는 개발자입니다.

92% Positional Error Reduction
79% p95 Latency Improvement
90%+ Long Tasks Reduction

2022.02 · 한국장학재단

우수 멘티

한국장학재단 사회 리더 대학생 멘토링 IT

2022.10 · 동작구청

우수 인재상

동작구청 우수 SW 인재

2025.05 · (주) 그랩

프로그래밍 우수상

(주) 그랩 우수 프로그램 개발

2025.05 · AWSKRUG

AWS한국사용자모임 발표

AI agent 스크립트 튜닝 관련 발표

ComputerScience

Development

Engineering

Trouble Shooting

GUESTBOOK

첫 마음부터
함께 나누는 온기

방명록 작성하러 가기

SUBSCRIBE

최신소식을
편하게 만나보세요.

DDD (Domain-Driven Design)

도입

“코드를 예쁘게 나누는 방법”이 아니라, 복잡한 비즈니스 규칙을 정확하게 모델링하는 설계 접근입니다.

개발을 하다 보면 기능은 동작하지만, 시간이 지나면서 “어디에 어떤 규칙이 있는지” 찾기 어려워지는 순간이 옵니다.
컨트롤러/서비스에 조건문이 늘어나고, 요구사항 변경 때마다 여러 곳을 동시에 수정해야 한다면 설계의 중심이 도메인(업무 개념)에서 벗어났을 가능성이 큽니다.

핵심 메시지

“DDD의 목적은 기술 중심 설계를 도메인 중심 설계로 바꾸는 것입니다.
즉, 코드가 업무 규칙을 더 잘 설명하도록 만드는 것”입니다.

- Domain-Driven Design 관점 -

 

정의

도메인 전문가의 언어와 개념을 코드 모델에 반영해 복잡한 시스템을 설계하는 방법입니다.

여기서 핵심은 프레임워크가 아니라 모델(Model)입니다. DDD는 “계층 구조를 이렇게 나누세요”보다, “우리 서비스의 핵심 개념과 규칙은 무엇인가?”, “그 규칙을 어디에 두어야 변경에 강한가?”를 먼저 묻습니다.

💡 TIP / DDD는 “대규모 프로젝트 전용”이 아니다

작은 프로젝트에서도 도메인 규칙이 자주 바뀌거나 복잡도가 높다면 DDD 사고방식은 큰 도움이 됩니다. 다만 모든 패턴을 한 번에 도입하기보다 용어 정리 → 경계 설정 → 핵심 규칙 캡슐화 순서로 적용하는 것이 좋습니다.

 

왜 필요한가

복잡한 서비스는 시간이 갈수록 “기능 추가”보다 “규칙 변경 대응”이 더 어려워집니다.
상황 DDD가 필요한 이유
비즈니스 규칙 증가 규칙을 엔티티/도메인 서비스에 모아 변경 영향 범위를 줄일 수 있음
팀 간 용어 불일치 유비쿼터스 언어(Ubiquitous Language)로 커뮤니케이션 비용 감소
서비스 확장/분리 Bounded Context 기준으로 경계를 나누기 쉬워짐
유지보수 난이도 상승 “기술 계층 중심”이 아닌 “업무 개념 중심”으로 구조를 재정렬 가능

 

DDD의 핵심 개념

DDD는 크게 전략적 설계전술적 설계로 나눠 이해하면 정리가 쉽습니다.

1. 전략적 설계 (Strategic Design)

시스템 전체를 어떤 경계로 나눌지, 팀/서비스 간 책임을 어떻게 분리할지 결정하는 단계입니다. “어디까지가 같은 도메인인가?”를 정하는 관점이라고 보면 됩니다.

유비쿼터스 언어 (Ubiquitous Language)

개발자, 기획자, 도메인 전문가가 같은 단어를 같은 의미로 쓰는 약속입니다. 예를 들어 “주문 확정”, “결제 완료”, “배송 시작”의 의미가 사람마다 다르면 코드와 문서도 바로 어긋납니다.

경계 컨텍스트 (Bounded Context)

같은 단어라도 컨텍스트가 다르면 의미가 달라질 수 있습니다. 예를 들어 “고객”이 주문 컨텍스트에서는 배송/결제 중심이고, 마케팅 컨텍스트에서는 세그먼트/캠페인 중심일 수 있습니다. DDD는 이 차이를 인정하고 경계를 분리합니다.

2. 전술적 설계 (Tactical Design)

경계 안에서 실제 코드를 어떻게 구성할지에 대한 패턴입니다. 흔히 DDD를 처음 접할 때 가장 많이 보는 부분이지만, 전략적 설계 없이 패턴만 가져오면 효과가 줄어듭니다.

요소 핵심 질문 설명
Entity “누구인가?” 식별자(ID)가 중요한 객체. 시간에 따라 상태가 변해도 같은 대상
Value Object “무엇인가?” 값 자체가 의미를 가짐. 불변(immutable)로 다루면 안정적
Aggregate “어디까지 함께 일관성을 보장할까?” 일관성 경계. Aggregate Root를 통해서만 내부를 변경
Repository “어떻게 저장/조회할까?” 도메인 관점에서 Aggregate를 로드/저장하는 인터페이스
Domain Service “이 규칙은 어느 객체의 책임인가?” 엔티티/VO에 넣기 애매한 도메인 규칙을 표현
Application Service “유스케이스를 어떻게 조합할까?” 트랜잭션/흐름 제어 담당. 비즈니스 규칙 자체는 도메인에 위임

 

DDD 구성 예시

예를 들어 “주문” 도메인에서는 주문 생성/결제/취소 규칙을 도메인 모델 중심으로 배치합니다.

예시 시나리오: 주문 취소

“배송 시작 전까지만 주문 취소 가능”이라는 규칙이 있다고 가정해봅시다. 이 규칙을 컨트롤러 if문에 두면 다른 API(관리자/배치/이벤트 소비자)에서 빠질 수 있습니다. 따라서 Order Aggregate 내부의 행동으로 두는 것이 안전합니다.

구조 관점

  • Controller: 요청/응답 처리
  • Application Service: 주문 조회 → 취소 호출 → 저장(트랜잭션)
  • Order Aggregate: 취소 가능 여부 검증 + 상태 변경
  • Repository: 저장소 구현(JPA/MyBatis 등)

 

DDD와 레이어드 아키텍처

DDD는 레이어드 아키텍처와 충돌하지 않습니다. 오히려 각 레이어의 책임을 더 명확하게 만듭니다.
레이어 역할
Presentation HTTP 요청/응답, 인증/인가 진입점, DTO 변환
Application 유스케이스 조합, 트랜잭션 경계, 외부 시스템 호출 orchestration
Domain 핵심 비즈니스 규칙, 상태 전이, 불변조건(invariant)
Infrastructure DB/JPA, 메시지 브로커, 외부 API, 파일 저장소 등 구현 세부사항

 

자주 하는 오해

DDD는 패키지 이름만 바꾸는 것이 아니라, 비즈니스 규칙의 위치를 재배치하는 작업입니다.

BAD

  • 도메인 규칙이 Controller/Service if문에 흩어짐
  • Entity가 단순 getter/setter 데이터 구조체가 됨
  • Repository가 쿼리 유틸처럼만 사용됨
  • “DDD 적용”인데 팀 용어 정의는 없음

GOOD

  • 핵심 규칙을 Aggregate 행동으로 캡슐화
  • 유스케이스 흐름은 Application Service에서 조합
  • 저장/외부 연동은 Infrastructure로 분리
  • 도메인 용어를 문서/코드/회의에서 통일

 

언제 쓰면 좋은가

DDD는 복잡한 규칙과 잦은 변경이 있는 도메인에서 특히 효과가 큽니다.

적합한 경우

  • 결제/정산/주문/권한/정책처럼 규칙이 많은 도메인
  • 기획 변경이 잦고 예외 케이스가 계속 늘어나는 서비스
  • 팀 규모가 커져 용어 불일치 비용이 커지는 조직

과한 경우(주의)

  • 단순 CRUD 중심의 관리 화면/백오피스 기능만 있는 경우
  • 도메인 규칙보다 화면/리포트/조회 쿼리가 중심인 경우
  • 팀이 DDD 용어/개념을 공유하지 않은 상태에서 패턴만 복붙하는 경우

 

실무 적용 순서

처음부터 모든 패턴을 도입하기보다, 문제가 큰 지점부터 점진적으로 적용하는 것이 현실적입니다.
1
핵심 도메인과 용어 정리 (기획/개발/운영이 같은 의미로 말하게 만들기)
2
변경이 잦은 유스케이스를 선택해 도메인 규칙을 엔티티/도메인 서비스로 이동
3
Aggregate 경계를 정의해 일관성 보장 범위 명확화
4
Repository/Infra 분리로 기술 구현과 도메인 규칙의 결합도 낮추기
5
테스트 전략 강화 (도메인 규칙 단위 테스트 + 유스케이스 통합 테스트)

 

정리

DDD는 “복잡한 비즈니스의 언어를 코드로 옮기는 설계”이며, 유지보수성과 협업 품질을 동시에 높이는 방법입니다.

✅ 핵심 요약

  • ✔️ DDD의 핵심은 프레임워크가 아니라 도메인 모델입니다.
  • ✔️ 전략적 설계는 경계(컨텍스트), 전술적 설계는 코드 패턴(엔티티/애그리거트 등)을 다룹니다.
  • ✔️ 비즈니스 규칙은 Controller가 아니라 도메인에 두는 것이 변경에 강합니다.
  • ✔️ DDD는 “한 번에 완성”이 아니라, 문제 많은 도메인부터 점진 적용하는 것이 현실적입니다.

 

728x90