도메인 주도 설계의 사실과 오해

2025-02-22

#DDD
도메인 주도 설계(DDD, Domain-Driven Desigin) 는 여전히 많은 기업과 개발자들 사이에서 각광을 받고 있다.
특히, 마이크로서비스 아키텍처(MSA) 가 확산이 되면서, DDD 의 개념이 적극적으로 활용되고 있다.
그렇다면, 도메인 주도 설계는 무엇이며, 도메인 주도 설계의 사실과 오해에 대해서 알아보자.

Intro

도메인 주도 설계가 처음 이야기 되었을 때와 현재의 도메인 주도 설계는 조금은 다르다고 할 수 있다.
하지만, 초창기의 도메인 주도 설계의 철학과 핵심 원칙에서는 크게 벗어나지는 않는다.
개인적으로 에릭 에반스가 작성한, "도메인 주도 설계 - 소프트웨어의 복잡성을 다루는 지혜" 책은 개발자라면, 읽어보기를 권장하고 싶고,

DDD 란 무엇인가?

도메인 주도 설계(Domain-Driven Design, DDD)는
복잡한 비즈니스 도메인을 효과적으로 다루기 위해 도메인 중심의 사고방식과 설계 원칙을 적용하는 철학적인 관점에 가깝다.
특정한 방법론이나 아키텍처가 아니라, 순수하게 비즈니스 중심으로 사고하는 방식 이다.

DDD 의 철학

복잡한 소프트웨어를 효과적으로 관리하고, 비즈니스 문제를 올바르게 모델링하여 해결 하는 것이 핵심 철학이다.

단순히 코드를 작성하는 것이 아니라, 도메인 전문가와 개발자가 협력하여 도메인을 깊이 이해하고, 이를 소프트웨어에 반영하는 방식 을 추구하는 것이고,
DDD 는 화려한 기술이나 기법, 마법이 아니라, 복잡한 소프트웨어를 효과적으로 관리하는 철학과 전략 이라고 할 수 있다.


DDD 의 핵심 원칙


1) 도메인과 모델 우선 (핵심 철학)

소프트웨어는 현실 세계의 복잡성을 해결하기 위한 것이므로, 도메인을 깊게 이해하고 모델을 만들어야 한다.

  • 기술적인 해결책 보다는 비즈니스 도메인 문제 해결을 우선시 한다.
  • 도메인 전문가와 협력하여 비즈니스 개념을 정확히 반영 해야 한다.
  • 도메인을 단순화 하고, 핵심 개념을 명확히 모델링 해야 한다.

2) 유비쿼터스 언어 (Ubiquitous Language)

도메인 전문가와 개발자가 같은 용어를 사용해야 오해를 줄이고, 효과적으로 협업할 수 있다.

  • 도메인 전문가와 개발자가 동일한 언어를 사용하여 커뮤니케이션해야 혼선이 일어나지 않는다.
  • 이 언어는 코드, 문서, 대화에서 일관되게 유지되어야 한다.
  • 모델과 코드가 유비쿼터스 언어를 반영해야 한다.

3) 바운디드 컨텍스트 (Bounded Context)

하나의 모델이 모든 곳에 통하지 않으므로, 모델의 적용 범위를 명확히 정의하는 바운디드 컨텍스트를 설정한다.

  • 하나의 도메인을 여러개의 경계(Context) 로 나눈다.
  • 각 컨텍스트 내에서 유비쿼터스 언어를 일관되게 적용한다.
  • 컨텍스트 간 관계를 명확히 정의하고, 통합 전략을 고민해야 한다.

4) 어그리게이트 (Aggregate)

무질서한 객체들 대신, 모델을 더 작은 단위로 구조화하여 일관성과 응집력을 가진 어그리게이트를 만들자.

  • 어그리게이트는 도메인 객체의 논리적 그룹이며, 일관성을 유지하는 단위이다.
  • Root Entity 가 변경을 관리하고, 외부에서 직접 내부 객체를 조작할 수 없다.
  • 트랜잭션 범위를 고려하여 적절한 크기로 모델링 해야 한다.

5) 도메인 이벤트 (Domain Event)

비즈니스 흐름을 명확하게 표현하기 위해 중요한 상태 변화는 이벤트로 명확하게 드러내자.

  • 도메인 내에서 중요한 상태 변화를 이벤트로 표현한다.
  • 이벤트 기반 설계를 활용하여 시스템 간 결합도를 낮춘다.
  • 이벤트는 과거 시제로 표현하며, 도메인 로직의 핵심 흐름을 반영해야 한다.

6) 리포지토리 (Repository)

데이터베이스가 아니라, 도메인 개념을 중심적으로 접근하여 도메인 객체의 저장과 검색을 추상화한다.

  • 리포지토리는 어그리게이트를 저장하고 검색하는 역할을 한다.
  • 도메인 로직에서 직접 데이터베이스 기술을 다루지 않는다.
  • 트랜잭션을 고려하여 적절한 데이터 접근 전략을 수립한다.

7) 어플리케이션 서비스 vs 도메인 서비스

도메인 로직과 어플리케이션 로직을 명확히 분리하여 비즈니스 로직과 어플리케이션 로직을 혼합하지 않는다.

  • 도메인 서비스 : 어그리게이트에 속하지 않는 도메인 로직을 처리한다.
  • 어플리케이션 서비스 : 트랜잭션, 외부 API 호출 등 어플리케이션 수준의 처리를 담당한다.
  • 도메인 로직은 도메인 모델 내에서 처리하고, 어플리케이션 로직은 별도로 관리해야 한다.

8) 전략적 설계 (Strategic Design)

DDD 는 단순한 전술적 패턴이 아니라 전략적 사고를 요구하므로 시스템 전체적인 설계를 고려해야 한다.

  • 핵심 도메인(Core Domain) 을 식별하고, 여기에 집중해야 한다.
  • 지원 서브도메인(Supporting Subdomain) 과 범용 서브도메인(Generic Subdomain)을 구분해야 한다.
  • 도메인의 전략적 우선순위를 정하고, 각 컨텍스트 간 협력 관계를 정의해야 한다.

DDD 핵심 원칙의 흐름


도메인 이해 → 유비쿼터스 언어 정립 → 바운디드 컨텍스트 설정 → 모델 구조화(어그리게이트, 이벤트, 리포지토리) → 전략적 설계 적용

DDD 의 철학은 소프트웨어가 도메인을 정확하게 반영해야 한다는 원칙 을 중심으로 전술적 패턴전략적 설계 로 체계화하는 것이다.


DDD 에 대한 사실과 오해

DDD 에 대한 사실
질문사실 ✅
특정한 아키텍처(ex: 헥사고날, MSA)를 강제하나요?특정한 아키텍처를 강제하지 않지만, 다양한 아키텍처에서 적용 가능하다.
도메인 모델을 처음부터 완벽하게 설계 해야하나요?DDD 는 반복적인 개발과 피드백을 통한 도메인 모델을 개선 하는 방식이다.
도메인 모델이 하나여야 하나요?하나의 시스템에서 여러개의 도메인 모델이 존재 할 수 있다.(바운디드 컨텍스트)
기술적인 요소보다 비즈니스 로직이 우선되어야 하나요?DDD 의 핵심은 비즈니스 로직을 먼저 고려 하는 것이다.
복잡한 도메인을 다룰 때 효과적인가요?비즈니스 로직이 복잡한 경우 DDD 를 적용하면 효과적이다.
도메인 전문가와의 협업은 필수 인가요?개발자와 도메인 전문과는 밀접한 관계를 가져야하고,
도메인 전문가와의 협업은 DDD 의 핵심요소 중 하나다.

❌ DDD 에 대한 오해 - MSA, 헥사고날, CQRS..
질문오해 ❌
반드시 MSA 나 헥사고날 아키텍쳐를 해야 하나요?무조건 MSA 를 해야 한다는 것은 오해이고,
MSA 가 각광을 받으면서 설명하기 쉬우니 DDD 로 예를 드는 것이다.
도메인 레이어만 분리가 잘되어 있다면 헥사고날이든 MSA 든 필요가 없다.
처음부터 모든 모델을 이벤트 스토밍으로 정의 해야 하나요?한 번에 모든 모델을 정의하는 것은 아니다.
CQRS 는 원래 DDD 의 일부였나요?CQRS 는 시스템 복잡성을 낮추기 위해서 나온 것이고,
DDD 는 복잡도가 높으면 나누자였는데,
현대의 DDD 에서는 CQRS 가 포함되는데, CQRS 가 DDD 의 복잡성을 해결하기 때문이다.
모든 프로젝트에서 반드시 필요한가?비즈니스 로직이 복잡한 프로젝트에는 적합
하지만, 단순한 CURD 시스템에서는 오히려 부담이 될 수 있다.

❌ DDD 에 대한 오해 - OOP
구분객체지향(OOP)도메인 주도 설계(DDD)
목적작은 문제 해결, 유지보수 용이한 코드 배치도메인 중심의 사고방식 적용
초점데이터알고리즘 을 객체 단위로 배치비즈니스 도메인 로직을 중심으로 코드 구성
본질기술적인 개념이 중심도메인의 본질을 코드로 표현하는 것이 중심
모델링 범위클래스, 인터페이스 등 기술적인 모델링바운디드 컨텍스트를 기반으로 도메인 모델링
변경 관리리팩토링을 통해 설계 개선도메인 전문가와 협업하여 지속적 리팩토링
객체지향은 기술적인 접근 방식이고, DDD 는 비즈니스 도메인을 중심으로 소프트웨어를 개발하는 방식이다.

현대의 DDD

1) CQRS 와 이벤트 소싱의 도입
  • 현래 DDD 의 일부는 아니었지만, 최근에는 복잡성을 해결하기 위해서 활용되고 포함해서 이야기 된다.
  • CQRS 는 읽기/쓰기 모델을 분리하여 성능을 개선할 수 있다.
  • 이벤트 소싱을 통해 상태 변경 이력을 추적 가능하게 한다.
2) MSA 와 DDD 의 관계
  • 바운디드 컨텍스트를 기반으로 MSA 를 설계 할 수 있다.
  • 그러나 DDD 를 한다고 반드시 MSA 를 도입할 필요는 없다.
3) 전략적 설계와 전술적 설계의 발전
  • 현대의 DDD 에서는 구체적인 전술 패턴(CQRS, 이벤트 소싱)과 전략 패턴(바운디드 컨텍스트, 컨텍스트 맵 등)이 발전
4) 점진적 도입 강조
  • 핵심 도메인부터 적용하고, 점신적으로 확장하는 방식이 현실적이다.
  • 처음부터 완벽한 설계를 하려 하기 보다 반복적인 리팩토링과 피드백을 통해 발전

CQRS (Command Query Responsibility Segregation) 란?

CQRS는 "명령(Command)와 조회(Query) 의 책임을 분리하는 아키텍처 패턴" 이다.
즉, 읽기(조회)와 쓰기(명령)을 별도의 모델로 나누어 설계하는 방식.
1) CQRS 의 핵심 개념
  • Command (명령)
    • 생성, 수정, 삭제와 같이 데이터를 변경하는 작업
    • 데이터 일관성과 트랜잭션을 유지하는 것이 중요
  • Query (조회)
    • 검색, 조회와 같이 데이터를 읽는 작업
    • 성능 최적활르 위해 별도의 읽기 모델을 구성할 수 있다.
2) CQRS 를 왜 사용할까?
  • 읽기/쓰기 성능 최적화가 가능하여 조회가 많은 시스템에서 빠른 성능을 제공할 수 있다.
  • 읽기와 쓰기를 각각 독립적으로 확장 가능하여 확장성이 향상된다.
  • 복잡한 도메인 로직을 분리하여 유지보수성이 개선된다.
그러나, 구현이 복잡해지고 유지보수가 어려워 질 수 가 있으며, 데이터 동기화가 필요할 수 있다.


정리
✔ DDD 의 핵심 철학은 비즈니스 도메인을 깊게 이해하고 소프트웨어에 정확히 반영하는 것이다.
✔ DDD 는 모든 프로젝트에 적용해야만 하는 것은 아니고, 비즈니스 복잡성에 따라 적절히 활용하는 것이다.
✔ 핵심 도메인에 집중하고, 변화에 유연하게 대응할 수 있도록 설계하는 것이 철학이라고 볼 수 있다.
✔ DDD 를 적용한다면 모든 문제를 해결할 수 있다는 것은 잘못됐다. 왜냐면 DDD 는 철학과 사상에 가깝기 때문이다.
✔ 도메인 전문가와 개발자가 끊임 없이 협력 유비쿼터스 언어로 소통하고 발전해나가는 것이 중요하다.

📚 Reference



🏷️ 같은 태그의 글 보기