본문 바로가기
WTIL

도메인 주도 설계란 (DDD)

by 다오__ 2025. 10. 26.

 

 

등장배경

이전의 기술 중심의 설계에서는 핵심 비즈니스 로직과 부가적 로직을 분리하지 않고 개발을 했다. 작은 서비스의 경우, 크게 문제가 없었지만, 시간이 지남에 따라, 로직들이 엉키고 각 객체간 의존성이 복잡하게 엮여있어 각각의 경계가 사라지고, 여러가지 문제가 발생하게 되었다. 특히 실무에서 흔하게 발생하는 요구사항이 바뀌거나, 비 개발자와 소통 시 서로 간 오해가 발생하고 비용이 증가되어 버렸다.

 

도메인 전문가와 개발자가 서로 협력해 해당 도메인 모델을 정의해 구분하고, 이를 활용해 소프트웨어를 개발/설계 하는 방법론이 DDD이다.

 

도메인(Domain)

도메인이란, 소프트웨어로 해결하고자 하는 핵심 비즈니스 영역으로써, 예를 들면 은행업무에서의 도메인 영역은 계좌 이체, 잔액 조회, 계좌 개설과 같이 은행에서 필수적으로 다뤄야할 비즈니스적 서비스를 의미하게 된다.

 

도메인 주도 설계 DDD(Domain Driven Design)

DDD는 이전 방식보다 비즈니스 복잡성 관리, 팀 커뮤니케이션, 모델 유지/확장 능력을 개선한다.핵심은 "도메인 모델"을 중심에 두고, 코드 구조와 팀의 언어를 그 모델에 맞추는 것이다.

  • 모델의 정확성 증가
    • 이전: 기술 중심 계층 설계 → 비즈니스 규칙이 흩어짐.
    • DDD: 도메인 개념이 코드에 직접 반영되어 의도와 구현 간 격차 감소.
  • 팀 간 의사소통 향상
    • 이전: 개발자·도메인전문가간 용어 불일치.
    • DDD: Ubiquitous Language로 공통언어 정립.
  • 복잡도 국지화(격리)
    • 이전: 전역 상태/로직이 여러 계층에 분산.
    • DDD: Bounded Context로 복잡한 서브도메인을 분리.
  • 유지보수성·진화성 개선
    • 이전: 변경이 전파되며 유연성 저하.
    • DDD: 도메인 중심 모듈화로 변경 영향범위 축소.
  • 비즈니스 우선 설계
    • 이전: 기술적 최적화 우선.
    • DDD: 핵심 도메인에 설계 자원 집중, 경쟁우위 확보.
  • 테스트 용이성·신뢰성 증가
    • 도메인 규칙이 객체/어그리게이트 내부에 모여 단위 테스트가 명확해짐.

 

DDD의 핵심 개념 - 전략적 설계

1. Bounded Context

의미: 모델이 유효한 경계. 한 컨텍스트 내부의 용어와 규칙은 다른 컨텍스트에 영향을 주지 않는다. Order라는 단어를 예로들면, 주문 컨텍스트에서는 "고객이 결제한 구매 행위", 배송 컨텍스트에서는 "배송 해야 할 패키지의 단위"로 의미가 다르다, 두 컨텍스트는 서로 다른 Order 모델을 가진다. 하지만 현실적으로는 이렇게 구별 되기 쉽지 않다. 이를 해결하기 위한 패턴이 있다.

 

파트너쉽 패턴: 두 컨텍스트가 대등한 입장에서 서로 협력, 둘 다 규칙을 정하는 상태. 주문과 결제 컨텍스트들은 서로 동등하며, 주문이 들어오면 반드시 결제 프로세스가 생성 되어야 하고, 반대로 결제 프로세스가 실패 시, 주문또한 무효화 되어야 한다.

 

공유 커널 패턴: 두 컨텍스트 중 핵심의 모델만을 공유하는 방식. 회원과 배송 컨텍스트는 일부를 제외하고 서로 간 독립적이다. 공통(핵심)부분을 공유 터널로 두고 운용한다.

 

순응주의자 패턴: 한쪽 컨텍스트가 다른 컨텍스트의 모델과 규칙을 그대로 따르는 패턴으로, 회계와 매출 컨텍스트들의 경우, 회계는 법적 규제를 따르고, 매출은 회계를 따라간다.

 

2. Context Map

의미: 여러 Bounded Context 사이의 관계를 명시적으로 표현한 지도.

 

3.Sub Domain(하위 도메인)

의미: 도메인을 더 작고 구분하기 쉽게 분리한 것을 하위 도메인이라 한다. 크게 3가지로 본다.

도메인마다 중요도가 다르다.

  • Core Domain: 비즈니스 경쟁력의 핵심. (예: 주문, 정산 로직)
  • Supporting Domain: 핵심을 보조. (예: 고객관리, 배송)
  • Generic Domain: 외부 솔루션 사용 가능. (예: 결제, 이메일 발송)

핵심 도메인에 개발 자원을 집중한다.

 

DDD의 핵심 개념 - 전술적 설계

개발자로써 고려해야할 부분이 전술적 설계다. 애플리케이션을 어떻게 설계하고 구현할 것인가에 초점을 맞춘다. 복잡도에 따라 설계방법을 선택해야한다.

 

트랜잭션 스크립트(Transaction Script Pattern)

하나의 업무처리 과정을 하나씩 처리하는 방식을 하나의 메서드로 만든다. 복잡하지 않은 도메인을 개발할 때 유용하다. 하지만 코드가 중복되고, 복잡해지면 유지보수가 힘들어진다.

 

빈약한 도메인 모델 (Anemic Domain Model)

위와 비슷한 개념으로, 도메인 모델에는 필드만 있고, 행동(Method)과 규칙(Validation)을 처리하는 로직이 서비스 계층에 몰려있는 형태로써, 구조가 단순하고 빠른 개발이 가능하다. 하지만 응집력이 사라지고, 도메인 모델은 껍질로만 존재하게 된다.

 

 

정교한 아키텍처 패턴

 

도메인 모델 ( Domain Model )

기존에서는 도메인 모델에 field만 가진 껍데기 형태로, 나머지 로직은 서비스 계층에서 담당했다. 도메인 모델에서는 도메인 내부에서 데이터(field) 와 행동(method) 그리고 책임(validation)을 함께 가진다. 핵심은 도메인이 주도권을 가지고 있는 형태이다. 도메인의 응집력이 높아지고 중복 제거, 테스트가 용이하다. 하지만 각각의 도메인을 관리하는데 관계를 잘못 잡으면 복잡도가 증가한다.

 

이벤트 소싱 (Event Sourcing)

기존에는 어떠한 로직을 처리하고, 그 결과 값 만을 저장해왔다면 "상태 변화"를 일으킨 이벤트를 저장하는 방식이다.

입금, 출금, 잔액 조회등 일어난 이벤트들을 전부 저장하고 재생하는 방식, 이벤트가 기록 되기 때문에 로그가 없더라도 변화, 이력 추적이 용이하다. 하지만 성능부담과, 이벤트가 잘못 재생 되는 경우, 커다란 서비스 문제로 확대될 수 있다.

 

CQRS ( Command Query Responseibility Segregation )

데이터 변경과 읽는 작업을 나누어 처리 하는 것이다. 예를들어, 주문 생성, 취소, 결제 도메인 모델들은 엄중하한 규칙을 거쳐 처리해야한다. (데이터의 변경작업) 하지만 조회의 경우, 도메인 규칙이 필요가 없다. 따라서 조회가 많은 서비스에서는 성능향상 기대할 수 있다. 이벤트 소싱과 결합 시 이벤트 기반 읽기전용 뷰를 구성가능하다. 하지만 복잡성과 설계, 운영 난이도가 높다.

 

 

계층형 아키텍처 (Layered Architecture)

가장 전통적인 아키텍처. 시스템을 기능적 관심사별로 층으로 나눈다.

 

  • Presentation Layer: UI, Controller. 사용자 요청 처리.
  • Application Layer: Use Case 구현. 트랜잭션 단위 관리.
  • Domain Layer: 비즈니스 로직의 중심 (Entity, VO, Domain Service).
  • Infrastructure Layer: DB, API, Message Broker 등 외부 연동.

 

 

헥사고날 아키텍처 (Hexagonal Architecture, Port & Adapter)

Alistair Cockburn 제안
“비즈니스 로직을 외부 기술로부터 완전히 분리하자”는 목표.DDD의 철학과 가장 궁합이 좋다.

  • Core: 도메인 로직 + 애플리케이션 로직.
  • Port: Core가 외부와 통신하기 위한 인터페이스.
  • Adapter: Port의 구현체. DB, REST API, UI 등.

추상화와 구체를 명확히 경계 짓는 패턴

포트는 외부와 연결짓는 "인터페이스", 어댑터는 포트에 맞춘 구현체

핵심(core)시스템은 외부와 연결되어있지 않다. 예를들어, 외부에서 Payment Port를 통해 핵심시스템으로 요청하려면, Payment Port를 구체화한 Adapter를 통해서만 요청할 수 있으며, 이 Adapter를 다양하게 구현해줄 수 있다.

(Kakao Payment Adapter) (Naver Payment Adapter) 등등

 

 

 

 

Onion 아키텍처 ( Clean Architecture )

계층이 원처럼 겹겹이 쌓여있는 구조

  • Infrastructure (외부 API 통신, DB 등)
  • Application Services (응용 계층, 오케스트레이션, 외부세계와 내부세계의 조정자역할)
  • Domain (도메인 모델, 규약, 핵심 비즈니스 로직)

Onion 아키텍처의 핵심은 의존성의 방향에 있다. 의존성은 바깥쪽에서부터 안쪽으로만 이루어질 수 있다. 반대 방향은 불가능하다. Inftastructure -> Application Services -> Domain (외부에서 내부로만 의존성을 가질 수 있음, 따라서 내부세계는 외부 어떤 것도 의존하지 않는다, 응집력)