맨위로가기

도메인 주도 설계

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

도메인 주도 설계(DDD)는 복잡한 소프트웨어 시스템 설계를 위한 접근 방식으로, 도메인 전문가와 개발자 간의 원활한 의사소통을 목표로 한다. DDD는 전략적 설계와 전술적 설계로 구성되며, 전략적 설계는 유비쿼터스 언어를 통해 공통의 이해를 형성하고 바운디드 컨텍스트로 도메인을 분할한다. 전술적 설계는 엔티티, 값 객체, 애그리게이트, 도메인 서비스, 리포지토리, 팩토리, 이벤트 등 구체적인 소프트웨어 구현 방식을 제시한다. DDD는 객체 지향 분석 및 설계, 모델 주도 아키텍처, 명령-쿼리 책임 분리, 이벤트 스토밍 등 다양한 개념과 관련이 있으며, 마이크로서비스 아키텍처에서 바운디드 컨텍스트를 통해 활용될 수 있다. DDD를 지원하는 다양한 도구와 프레임워크가 존재한다.

더 읽어볼만한 페이지

  • 소프트웨어 설계 - 구조적 분석
    구조적 분석은 1960년대에서 1980년대 소프트웨어 개발의 복잡성을 해결하기 위해 개발된 기법으로, 다이어그램과 데이터 사전을 활용하여 시스템을 분석하고 설계했으며, 객체 지향 프로그래밍의 등장으로 활용도가 감소했다.
  • 소프트웨어 설계 - 지속적 배포
    지속적 배포(CD)는 소프트웨어 릴리스 프로세스를 자동화하는 접근 방식이며, 배포 파이프라인을 통해 구현되고 시장 출시 시간 단축, 제품 품질 향상 등의 이점을 제공하지만 테스트 자동화 부족 등의 과제도 존재한다.
  • 소프트웨어 개발 철학 - 애자일 소프트웨어 개발
    애자일 소프트웨어 개발은 1990년대에 등장하여 개인과 상호작용, 작동하는 소프트웨어, 고객과의 협력, 변화에 대한 대응을 핵심 가치로 삼고 적응형 계획과 반복적 실행을 통해 시장 출시 속도와 위험 완화를 추구하는 소프트웨어 개발 방법론이다.
  • 소프트웨어 개발 철학 - 유닉스 철학
    유닉스 철학은 단순성, 모듈성, 재사용성을 중시하며, 한 가지 일을 잘하는 프로그램, 협력적인 프로그램, 텍스트 스트림 처리 프로그램을 지향하는 소프트웨어 설계 원칙으로, 현대 운영체제 및 소프트웨어 설계에 영향을 주지만 비판도 존재한다.
  • 소프트웨어 구조 - Ajax
    Ajax는 웹 페이지 전체를 새로고침하지 않고 비동기적으로 서버와 통신하여 웹 애플리케이션의 일부를 업데이트하는 웹 개발 기술로, XMLHttpRequest 객체의 등장으로 가능해졌으며 HTML, CSS, DOM, JavaScript, JSON 등의 기술을 통합하여 동적인 사용자 인터페이스를 구현한다.
  • 소프트웨어 구조 - 멀티테넌시
    멀티테넌시는 단일 애플리케이션 인스턴스로 여러 고객에게 서비스를 제공하여 SaaS 및 클라우드 환경에서 비용과 관리 효율성을 높이고 데이터 활용 가치를 창출하는 소프트웨어 아키텍처 방식이다.
도메인 주도 설계
개요
도메인 주도 설계의 예시
도메인 주도 설계 예시
설계 패러다임소프트웨어 설계
고안자에릭 에반스
첫 공개2003년
설명
핵심복잡성을 해결하기 위한 접근 방식
목표소프트웨어 개발자가 특정 문제 영역에 대한 이해도를 높이는 것
특징도메인 전문가와 개발자 간의 긴밀한 협력
공유 언어 (Ubiquitous Language) 사용
도메인 모델을 중심으로 설계
전략적 설계와 전술적 설계
주요 개념
바운디드 컨텍스트 (Bounded Context)도메인 모델이 적용되는 특정 경계
유비쿼터스 언어 (Ubiquitous Language)도메인 전문가와 개발자가 공유하는 공통 언어
엔티티 (Entity)고유 식별자를 가진 객체
값 객체 (Value Object)불변하며 속성으로 정의되는 객체
애그리거트 (Aggregate)일관성을 유지하기 위한 엔티티 및 값 객체의 클러스터
리포지토리 (Repository)애그리거트의 영속성을 관리하는 메커니즘
도메인 서비스 (Domain Service)특정 엔티티에 속하지 않는 도메인 로직
이벤트 (Event)도메인에서 발생하는 중요한 사건
전략적 설계
컨텍스트 맵 (Context Map)여러 바운디드 컨텍스트 간의 관계를 보여주는 다이어그램
공유 커널 (Shared Kernel)여러 팀이 공유하는 도메인 모델의 일부
고객-공급자 (Customer-Supplier)한 팀이 다른 팀의 요구를 충족하는 관계
준수주의자 (Conformist)하위 팀이 상위 팀의 모델을 따르는 관계
부패 방지 계층 (Anti-Corruption Layer)다른 시스템과의 통합 시 모델의 손상을 방지하는 계층
분리된 방식 (Separate Ways)더 이상 관련이 없는 두 팀이 각자의 모델을 개발하는 방식
전술적 설계
엔티티 (Entity)고유 식별자를 가진 객체
값 객체 (Value Object)불변하며 속성으로 정의되는 객체
애그리거트 (Aggregate)일관성을 유지하기 위한 엔티티 및 값 객체의 클러스터
팩토리 (Factory)복잡한 객체 생성을 캡슐화하는 메커니즘
리포지토리 (Repository)애그리거트의 영속성을 관리하는 메커니즘
서비스 (Service)특정 엔티티에 속하지 않는 도메인 로직
이벤트 (Event)도메인에서 발생하는 중요한 사건
장점
복잡성 관리복잡한 도메인을 더 작은, 관리하기 쉬운 부분으로 분할
비즈니스 가치비즈니스 요구 사항에 더 잘 맞는 소프트웨어 개발
유지보수성명확하고 이해하기 쉬운 코드 기반
협업도메인 전문가와 개발자 간의 효과적인 협업 촉진
단점
학습 곡선새로운 개념과 패턴을 배우는 데 시간과 노력이 필요함
초기 투자초기 모델링 및 설계 단계에 더 많은 시간과 노력이 필요함
오버 엔지니어링간단한 문제에 지나치게 복잡한 솔루션을 적용할 수 있음
관련 서적
도메인 주도 설계 (Domain-Driven Design: Tackling Complexity in the Heart of Software)에릭 에반스 저
패턴, 원칙, 도메인 기반 설계 사례 (Patterns, Principles, and Practices of Domain-Driven Design)스콧 밀렛, 닉 튠 저
도메인 주도 설계 구현 (Implementing Domain-Driven Design)본 버논 저

2. 역사적 배경

DDD는 2003년 에릭 에반스의 저서 "Domain-Driven Design: Tackling Complexity in the Heart of Software"를 통해 처음 소개되었다.Domain-Driven Design: Tackling Complexity in the Heart of Software|도메인 주도 설계: 소프트웨어의 심장에서 복잡성을 다루기영어

3. 주요 개념

도메인 주도 설계(DDD)는 소프트웨어 개발에서 사용자가 프로그램을 적용하는 대상 영역인 '도메인'을 중심으로 설계하는 방식이다. DDD는 크게 전략적 설계전술적 설계로 나뉜다.[23]

DDD에서 중요하게 생각하는 것은 도메인 전문가, 사용자, 개발자가 공유하는 공통 언어인 '유비쿼터스 언어'이다. 이 언어는 도메인 모델과 시스템 요구사항을 설명하는 데 사용된다.[6]

객체 지향 다중 계층 아키텍처에서 도메인 계층은 일반적인 계층 중 하나이다.

3. 1. 전략적 설계

도메인 주도 설계(DDD)에서 전략적 설계는 비즈니스 도메인을 이해하고, 도메인의 핵심 개념과 규칙을 정의하는 과정이다. DDD는 크게 전략적 설계전술적 설계로 나뉜다. 전략적 설계에서는 유비쿼터스 언어, 바운디드 컨텍스트 같은 개념을 도입하고, 사업 활동을 그 성질에 따라 여러 업무 영역으로 분류한다.

전략적 설계는 다음과 같은 주요 개념들을 포함한다.

  • 유비쿼터스 언어: 도메인 전문가와 개발자가 동일한 용어를 사용하여 의사소통하는 것을 의미하며, 도메인 모델과 시스템 요구사항을 설명하는 데 사용된다.
  • 바운디드 컨텍스트: 특정 도메인 모델이 적용되는 범위를 의미한다. 시스템을 여러 바운디드 컨텍스트로 나누어 각 컨텍스트가 자체 모델을 가지도록 한다.
  • 컨텍스트 매핑: 더 큰 시스템 내에서 서로 다른 도메인 또는 하위 도메인의 경계를 식별하고 정의하는 것이다.
  • 도메인 분류: 소프트웨어를 핵심 업무 영역, 일반적인 업무 영역, 보완적인 업무 영역으로 나눈다.
  • 핵심 업무 영역(코어 서브도메인): 프로젝트의 핵심이 되는 복잡하고 중요한 로직을 포함하는 부분이다. 사업에서 전략적으로 강점이 되는 부분이며, 잦은 변경이 예상된다.[24]
  • 일반적인 업무 영역(제네릭 서브도메인): 모든 소프트웨어에서 기본적으로 접근 방식이 변하지 않는 부분으로, 외부 소프트웨어 및 라이브러리 활용을 고려할 수 있다.[24]
  • 보완적인 업무 영역(서포팅 서브도메인): 사업 활동을 지원하지만, 경쟁 우위를 창출하지 않는 부분이다. 비교적 단순한 로직을 가지며, 변경이 적다.[24]


사업 활동은 핵심 업무 영역(코어 도메인), 일반적인 업무 영역(제네릭 서브 도메인), 보완적인 업무 영역(서포팅 서브도메인)으로 분류된다.[24]

3. 1. 1. 유비쿼터스 언어 (Ubiquitous Language)

도메인 주도 설계에서 유비쿼터스 언어(Ubiquitous language영어)는 도메인 전문가와 개발자가 동일한 용어를 사용하여 의사소통하는 것을 의미한다.[24][25] 이는 도메인 모델과 시스템 요구사항을 설명하는 데 사용되며, 코드(예: 클래스명, 클래스 메서드, 클래스 변수)에도 반영되어 비즈니스 도메인과의 일관성을 유지한다. 예를 들어, 대출 신청을 처리하는 소프트웨어는 "loan application", "customer"와 같은 클래스 이름이나 "accept offer", "withdraw"와 같은 메서드를 가질 수 있다.

같은 용어를 사용함으로써 도메인 전문가와 기술자 간의 효율적인 의사소통을 촉진하는 것이 도메인 주도 설계의 전략적 기법이다.[24]

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

바운디드 컨텍스트(Bounded Context)는 특정 도메인 모델이 적용되는 범위를 의미한다. 마틴 파울러에 따르면, 도메인이 커질수록 단일 통합 모델을 구축하는 것은 어려워진다.[26] 이는 사업 영역에서 같은 단어라도 문맥에 따라 다른 의미를 가지는 경우가 생기기 때문이다.

DDD에서는 시스템 전체가 단일 통합 모델을 가진다는 생각에 반대하며, 시스템을 여러 바운디드 컨텍스트로 나누는 것을 권장한다. 바운디드 컨텍스트는 각각 자체 모델을 가진다.[27]

바운디드 컨텍스트는 같은 단어에 같은 의미를 적용할 수 있는 범위이다. DDD(도메인 주도 설계)에서는 도메인 전문가와 기술자 간에 동일한 단어를 사용하여 업무에 대한 공통 이해를 형성한다.[24][25] 그러나 동일한 사업 영역 내에서도 배경이 다르면 서로 다른 의미를 갖는 단어가 존재한다. 이러한 모호함을 해소하기 위해 DDD에서는 바운디드 컨텍스트라는 개념을 도입한다.[24]

바운디드 컨텍스트는 언어학에서의 의미론적 영역에 기초한다. 의미론적 영역은 같은 단어가 같은 의미로 사용되는 범위를 지칭한다. 예를 들어 "토마토"가 식물학적 문맥에서는 "열매"인 반면, 법적 문맥에서는 "채소"인 경우가 있다.[24]

마이크로서비스 아키텍처에서 바운디드 컨텍스트는 종종 마이크로서비스에 매핑되지만, 이러한 관계는 설계 접근 방식에 따라 달라질 수 있다. 각 바운디드 컨텍스트가 단일 마이크로서비스로 구현되는 일대일 관계는 명확한 경계를 유지하고, 결합도를 줄이며, 독립적인 배포 및 확장을 가능하게 하므로 일반적으로 이상적이다. 그러나 다른 매핑도 적절할 수 있다. 바운디드 컨텍스트를 다양한 확장성 또는 기타 운영 요구 사항을 해결하기 위해 여러 마이크로서비스로 분할할 때 일대다 관계가 발생할 수 있으며, 단순화 또는 운영 오버헤드를 최소화하기 위해 여러 바운디드 컨텍스트를 단일 마이크로서비스로 통합할 수 있는 다대일 관계가 발생할 수 있다. 관계 선택은 시스템의 비즈니스 목표, 기술적 제약 및 운영 요구 사항과 함께 DDD 원칙의 균형을 맞춰야 한다.[16]

3. 1. 3. 컨텍스트 매핑 (Context Mapping)

컨텍스트 매핑은 더 큰 시스템 내에서 서로 다른 도메인 또는 하위 도메인의 경계를 식별하고 정의하는 것이다. 이는 이러한 컨텍스트가 서로 어떻게 상호 작용하고 관련되는지 시각화하는 데 도움이 된다. 에릭 에반스(Eric Evans)에 따르면 다음과 같은 패턴이 있다:[8]

  • 파트너십
  • 공유 커널
  • 고객/공급자 개발
  • 순응자
  • 부패 방지 계층
  • 개방형 호스트 서비스
  • 게시된 언어
  • 별도의 방식
  • 진흙 덩어리

3. 1. 4. 도메인 분류

도메인 주도 설계(DDD)에서는 소프트웨어를 핵심 업무 영역, 일반적인 업무 영역, 보완적인 업무 영역으로 나눈다. DDD의 중요하고 주요한 목적 중 하나는 전력을 핵심 업무 영역에 집중시키는 것이다.[29]

어떤 소프트웨어에서 핵심 업무 영역이더라도, 다른 소프트웨어에서는 일반적인 업무 영역일 수 있다.

  • 핵심 업무 영역(Core subdomain|코어 서브도메인영어): 프로젝트의 핵심이 되는 복잡하고 중요한 로직을 포함하는 부분이다. 도메인 모델 등 복잡한 업무 로직을 처리하기 위한 디자인 패턴(전술적 설계)을 선택하는 것을 고려할 수 있다. 사업에서 전략적으로 강점이 되는 부분이며, 잦은 변경이 예상된다.[24]
  • 일반적인 업무 영역(Generic subdomain|제네릭 서브도메인영어): 모든 소프트웨어에서 기본적으로 접근 방식이 변하지 않는 부분이며, 따라서 외부 소프트웨어 및 라이브러리를 활용하는 것을 고려할 수 있다.[24] 예를 들어 인증 처리를 들 수 있다.
  • 보완적인 업무 영역(Supporting subdomain|서포팅 서브도메인영어): 사업 활동을 지원하지만, 경쟁 우위를 창출하지 않는 부분이다. 보완적인 업무 영역의 로직은 단순하고 변경이 적다고 여겨지며, 트랜잭션 스크립트나 액티브 레코드와 같은 간이한 업무 로직 표현 방법을 사용하는 것이 적합하다고 여겨진다.[24]

3. 2. 전술적 설계

전술적 설계는 전략적 설계를 바탕으로 실제 코드를 작성하는 과정이다. DDD에서 전략을 달성하기 위해, 구체적으로 어떻게 업무 로직을 표현하고 소프트웨어를 구현할 것인가에 대해 논의한다.[24]

업무 로직 표현 방법으로는 트랜잭션 스크립트, 액티브 레코드, 도메인 모델, 이벤트 소싱 도메인 모델 등이 있다.[24]

전술적 설계에는 다음과 같은 패턴들이 있다.

패턴설명
엔티티속성이 아닌 고유한 식별자를 통해 구분되는 객체
값 객체속성을 포함하지만 개념적인 식별자를 갖지 않는 불변 객체
애그리게이트여러 엔티티로 구성되며, 영속화에서 데이터의 일관성이 요구되는 트랜잭션 단위
도메인 서비스특정 엔티티나 값 객체에 속하지 않는 도메인 로직을 표현하는 객체
리포지토리데이터 저장소(예: 데이터베이스)에서 도메인 객체를 검색하는 메서드를 가진 객체
팩토리도메인 객체를 직접 생성하는 메서드를 가진 객체
이벤트과거에 발생한 일을 나타냄. 도메인 이벤트는 도메인 전문가가 중요하게 생각하는 이벤트


3. 2. 1. 엔티티 (Entity)

엔티티는 속성이 아닌 고유한 식별자를 통해 구분되는 객체이다. 예를 들어, 대부분의 항공사는 모든 항공편의 좌석에 고유한 번호를 할당하는데, 이것이 바로 좌석의 식별자가 된다.[6] 엔티티는 식별자에 의해 동일성이 식별되며, 상태가 변하는 가변 객체이다.[24]

3. 2. 2. 값 객체 (Value Object)

값 객체는 속성을 포함하지만 개념적인 식별자를 갖지 않는 불변 객체이다.[6] 예를 들어, 사람들이 명함을 교환할 때 각 고유한 카드를 구별하기보다는 카드에 있는 정보(속성)에만 관심을 갖는다.[6]

값 객체는 속성의 조합에 의해 동일성이 식별되는 불변 객체이다.[24] 예를 들어, 어떤 사람이 명함을 교환하는 경우, 명함의 내용(속성)에만 관심을 가지며 명함 한 장 한 장을 개별적으로 취급하지 않는다.[24]

3. 2. 3. 애그리게이트 (Aggregate)

애그리게이트는 여러 엔티티로 구성되며, 영속화에서 데이터의 일관성이 요구되는 트랜잭션 단위이다.[24] 애그리게이트는 루트 엔티티에 의해 함께 묶인다. 애그리게이트 외부의 객체는 루트에 대한 참조는 가질 수 있지만, 애그리게이트의 다른 객체에 대한 참조는 가질 수 없다. 애그리게이트 루트는 애그리게이트 내의 변경 사항의 일관성을 검사한다.[6] 예를 들어, 운전자는 자동차의 각 바퀴를 개별적으로 제어할 필요가 없다. 그들은 단순히 차를 운전한다. 이 맥락에서, 자동차는 엔진, 브레이크, 헤드라이트 등 여러 다른 객체의 애그리게이트이다.[6]

예를 들어, Book과 Stock이라는 엔티티가 있고, 이들이 Book 애그리게이트를 형성하고 있다고 하면, 여기서 루트는 Book 엔티티이다. 애그리게이트에서 루트가 되는 엔티티가 영속화에서의 인터페이스가 된다.[24]

3. 2. 4. 도메인 서비스 (Domain Service)

도메인 서비스는 특정 엔티티나 값 객체에 속하지 않는 도메인 로직을 표현하는 객체이다.[24] 엔티티나 값 객체에 구현하기 부자연스러운 업무 로직을 구현하기 위해 사용되는 상태가 없는 객체이다.[24]

3. 2. 5. 리포지토리 (Repository)

도메인 주도 설계에서 리포지토리는 데이터 저장소(예: 데이터베이스)에서 도메인 객체를 검색하는 메서드를 가진 객체이다.[24] 리포지토리는 애그리게이트의 영속성을 처리하는 데 사용되며, 애그리게이트의 입출력 단위의 인터페이스(포트) 역할을 한다.[39][40]

일반적인 패턴에서는 인프라스트럭처 계층이 도메인 모델의 포트(리포지토리)를 구현하고, 유스케이스가 리포지토리를 이용하여 애그리게이트를 입출력한다.

3. 2. 6. 팩토리 (Factory)

팩토리는 도메인 객체를 직접 생성하는 메서드를 가진 객체이다.[1]

3. 2. 7. 이벤트 (Event)

DDD에서 이벤트는 과거에 발생한 일을 나타낸다. 도메인 이벤트는 도메인 전문가가 중요하게 생각하는 이벤트이다.[7]

이벤트 이력 방식의 도메인 모델에서는 집합의 상태 변화를 도메인 이벤트로 표현한다. 도메인 모델 패턴에서는 집합의 상태를 영속화하는 반면, 이벤트 이력 방식의 도메인 모델에서는 집합의 상태 변화를 나타내는 도메인 이벤트를 영속화한다.[24]

이 패턴은 과거 특정 시점의 상태를 얻을 수 있다는 장점이 있는 반면, 현재 상태를 재현하기 위해 계산이 필요하다는 단점이 있다. 이에 대해서는 테이블이 갱신될 때마다 최신 상태를 투영한 뷰를 갱신하고, CQRS 패턴을 사용하여 읽기 모델에서 이 뷰를 참조함으로써 대응할 수 있다고 한다.[24][36]

3. 3. 업무 로직 표현 방법

DDD에서는 복잡도에 따라 다양한 방식으로 업무 로직을 표현할 수 있다. 블라드 코노노프는 단순한 업무 로직 구현 방법으로 트랜잭션 스크립트와 액티브 레코드를, 복잡한 업무 로직에는 도메인 모델, 그리고 이를 확장한 이벤트 히스토리형 도메인 모델을 제시했다.[24]

하위 섹션에서 각 방법에 대한 자세한 내용을 다루고 있으므로, 여기서는 간단하게 언급만 하고 넘어간다.

3. 3. 1. 트랜잭션 스크립트 (Transaction Script)

Transaction Script영어는 프레젠테이션 계층에서 전달되는 요청을 처리하는 일련의 흐름 속에서 업무 로직을 표현하는 절차적인 업무 로직 구현 방법이다.[24][30]

3. 3. 2. 액티브 레코드 (Active Record)

액티브 레코드(Active Record영어)는 도메인 모델의 일종으로, 모델이 데이터베이스의 테이블 또는 뷰와 일대일로 대응한다. 액티브 레코드의 객체는 데이터베이스의 테이블 레코드를 표현하며, 레코드를 표현하는 객체 자체가 영속화 등의 데이터 액세스 처리를 수행한다.[24][31]

액티브 레코드를 사용하는 장점은 구조가 단순하고, 데이터베이스 조작이 직관적이라는 점이다. 액티브 레코드를 사용하는 경우에도 업무 로직은 트랜잭션 스크립트로 기술한다. 이 경우, 코드는 데이터베이스를 직접 조작하는 것이 아니라, 액티브 레코드 객체를 조작한다.[24][32][33]

액티브 레코드의 단점은 테이블과 모델이 일대일로 대응하기 때문에, 모델이 데이터베이스 구조에 의존하게 되고, 도메인 모델로서의 유연성이 떨어진다는 점이다.[33]

액티브 레코드의 목적은 데이터베이스 조작의 최적화라고 여겨진다.[24]

3. 3. 3. 도메인 모델 (Domain Model)

도메인 모델(Domain Model영어)은 업무 로직과 데이터를 모두 통합하여 사업 활동을 표현하는 객체 모델이다[34]. 도메인 모델은 다른 계층의 지식에 의존하지 않고 업무 지식을 표현하는 것이 바람직하며, 그 점에서 후술할 포트와 어댑터 패턴과 궁합이 좋다[24].

전형적인 도메인 모델은 애그리게이트와 이를 구성하는 엔티티, 값 객체, 도메인 서비스로 표현된다. 애그리게이트는 도메인 모델의 영속성에서 트랜잭션의 단위이며, 업무 로직은 엔티티나 값 객체의 필드 또는 메서드로 정의되는 것 외에도, 여기에 정의하는 것이 부자연스럽거나 로직이 애그리게이트를 넘나들며 존재하는 경우, 이는 도메인 서비스로 표현된다.

도메인 모델이 가져야 할 정보가 도메인 모델 밖에 기록되어 있어 업무 지식이 새어나가는 상태를 "도메인 모델 빈혈증"이라고 부르기도 한다.

도메인 모델 패턴에서는 개발자가 도메인 모델을 순수하고 유용한 구조로 유지하기 위해 일반적으로 많은 분리와 캡슐화를 수행해야 하는 반면, 유지 보수성 등의 이점을 제공하기 때문에 마이크로소프트는 도메인에 대한 공통 이해를 구축함으로써 명확한 이점이 있는 복잡한 업무 영역에만 도메인 모델 패턴을 도입할 것을 권장하고 있다[20].

3. 3. 4. 이벤트 소싱 (Event Sourcing)

이벤트 소싱은 엔티티가 내부 상태를 추적할 때 직접적인 직렬화나 객체-관계 매핑 대신, 이벤트 저장소에 이벤트를 읽고 기록하는 방식을 사용하는 아키텍처 패턴이다.

도메인 주도 설계(DDD)와 CQRS를 함께 사용하면, 애그리거트 루트는 명령을 검증하고 적용하는 역할을 하며(주로 명령 처리기에서 해당 인스턴스 메서드를 호출하여), 그 후 이벤트를 게시한다. 이는 애그리거트 루트가 메서드 호출을 처리하는 논리의 기반이 된다. 따라서 입력은 명령이고 출력은 이벤트 저장소에 저장되는 하나 이상의 이벤트이며, 애플리케이션의 뷰와 같이 관심 있는 대상을 위해 메시지 브로커에 게시되는 경우가 많다.

애그리거트 루트를 모델링하여 이벤트를 출력하면, 일반적인 'n'-티어 데이터 전달 아키텍처에서 엔티티로부터 읽기 데이터를 투영하는 것보다 내부 상태를 더욱 격리할 수 있다. 중요한 장점 중 하나는 공리적 정리 증명기(예: Microsoft Contracts 및 CHESS)[14]를 더 쉽게 적용할 수 있다는 것이다. 애그리거트 루트가 내부 상태를 완전히 숨기기 때문이다. 이벤트는 주로 애그리거트 루트 인스턴스의 버전을 기반으로 유지되므로, 낙관적 동시성 제어를 통해 분산 시스템에서 동기화되는 도메인 모델이 생성된다.

이벤트 이력 방식의 도메인 모델에서는 집합의 상태 변화를 도메인 이벤트로 표현한다. 도메인 모델 패턴에서는 집합의 상태를 영속화하는 반면, 이벤트 이력 방식의 도메인 모델에서는 집합의 상태 변화를 나타내는 도메인 이벤트를 영속화한다.[24]

이 패턴은 과거 특정 시점의 상태를 얻을 수 있다는 장점이 있지만, 현재 상태를 재현하기 위해 계산이 필요하다는 단점이 있다. 이에 대해서는 테이블이 갱신될 때마다 최신 상태를 투영한 뷰를 갱신하고, CQRS 패턴을 사용하여 읽기 모델에서 이 뷰를 참조함으로써 대응할 수 있다고 한다.[24][36]

4. 다른 개념과의 관계

DDD는 객체 지향 프로그래밍의 장점을 활용하며, 여기에는 명령/메서드 호출을 수신하는 객체/애그리게이트 루트, 최우선 애그리게이트 루트 내의 상태 캡슐화, 그리고 더 높은 아키텍처 수준에서 바운디드 컨텍스트가 포함된다.[6] DDD는 Plain Old Java Objects 및 Plain Old CLR Objects와 관련이 있는데, 이는 각각 자바와 .NET Framework에 특정한 기술적 구현 세부 사항이다.[6]

DDD는 모델 주도 아키텍처(MDA)와 호환되지만,[10] 두 개념의 의도는 다르다. MDA는 더 나은 도메인 모델을 정의하는 것보다 모델을 다양한 기술 플랫폼에 대한 코드로 변환하는 데 더 중점을 둔다.[10]

명령-쿼리 책임 분리(CQRS)는 데이터를 읽는 '쿼리'와 데이터를 쓰는 '명령'을 분리하는 아키텍처 패턴이다.[9] CQRS는 버트란드 메이어가 만든 명령과 쿼리 분리(CQS)에서 파생되었다.

이벤트 스토밍은 DDD에서 도메인 이벤트를 찾고 이해하기 위해 사용되는 협업 워크숍 모델링 기법이다. 이 과정에는 이해 관계자, 도메인 전문가, 개발자가 함께 참여하여 도메인 이벤트의 흐름, 원인, 결과를 시각화하고 도메인에 대한 공통된 이해를 돕는다.[12][13]

4. 1. 객체 지향 분석 및 설계 (Object-Oriented Analysis and Design)

DDD는 객체 지향 프로그래밍의 장점을 활용한다. 여기에는 명령/메서드 호출을 수신하는 객체/애그리게이트 루트, 최우선 애그리게이트 루트 내의 상태 캡슐화, 그리고 더 높은 아키텍처 수준에서 바운디드 컨텍스트가 포함된다.[6] DDD는 Plain Old Java Objects 및 Plain Old CLR Objects와 관련이 있는데, 이는 각각 자바와 .NET Framework에 특정한 기술적 구현 세부 사항이다.[6] 이러한 용어는 도메인 객체가 특정 기술 프레임워크가 아닌 도메인의 비즈니스 동작에 의해 순수하게 정의되어야 한다는 견해를 반영한다.[6]

4. 2. 모델 주도 아키텍처 (Model-Driven Architecture, MDA)

도메인 주도 설계(DDD)는 모델 주도 아키텍처(MDA)와 호환되지만,[10] 두 개념의 의도는 다르다. MDA는 더 나은 도메인 모델을 정의하는 것보다 모델을 다양한 기술 플랫폼에 대한 코드로 변환하는 데 더 중점을 둔다.[10]

그러나 모델 주도 엔지니어링에서 제공하는 기술(도메인 모델링, 도메인 전문가와 개발자 간의 의사 소통을 용이하게 하기 위한 도메인 특화 언어 생성 등)은 실제로 도메인 주도 설계를 용이하게 하고 실무자가 모델을 최대한 활용하도록 돕는다. 모델 주도 엔지니어링의 모델 변환 및 코드 생성 기술 덕분에 도메인 모델은 이를 관리할 실제 소프트웨어 시스템을 생성하는 데 사용될 수 있다.[11]

4. 3. 명령-쿼리 책임 분리 (Command Query Responsibility Segregation, CQRS)

명령-쿼리 책임 분리(CQRS)는 데이터를 읽는 '쿼리'와 데이터를 쓰는 '명령'을 분리하는 아키텍처 패턴이다.[9] CQRS는 버트란드 메이어가 만든 명령과 쿼리 분리(CQS)에서 파생되었다.

명령은 상태를 변경하며, 애그리게이트 루트 또는 엔티티에 대한 메서드 호출과 거의 같다. 쿼리는 상태를 읽지만 변경하지 않는다.

CQRS는 도메인 주도 설계를 필수로 요구하지는 않지만, 애그리게이트 루트의 개념을 통해 명령과 쿼리의 구분을 명확히 한다. 주어진 애그리게이트 루트는 명령에 해당하는 메서드를 가지며, 명령 처리기는 애그리게이트 루트에서 해당 메서드를 호출한다.

애그리게이트 루트는 연산의 로직을 수행하고 실패 응답을 반환하거나 자체 상태를 변경하여 데이터 저장소에 기록할 수 있다. 명령 처리기는 애그리게이트 루트의 상태를 저장하고 필요한 컨텍스트(예: 트랜잭션)를 생성하는 것과 관련된 인프라 관련 문제를 처리한다.

4. 4. 이벤트 스토밍 (Event Storming)

이벤트 스토밍은 도메인 주도 설계 (DDD)에서 도메인 이벤트를 찾고 이해하기 위해 사용되는 협업 워크숍 모델링 기법이다. 이 과정에는 이해 관계자, 도메인 전문가, 개발자가 함께 참여하여 도메인 이벤트의 흐름, 원인, 결과를 시각화하고 도메인에 대한 공통된 이해를 돕는다. 이 기법은 색깔 있는 스티커 메모를 사용하여 도메인 이벤트, 애그리게이트, 외부 시스템과 같은 다양한 요소를 나타내어 도메인을 명확하고 구조적으로 탐구할 수 있게 한다.[12][13]

이벤트 스토밍은 DDD의 핵심 구성 요소인 서브도메인, 바운디드 컨텍스트, 애그리게이트 경계를 발견하는 데 도움을 준다. 도메인에서 '무엇이 발생하는지'에 초점을 맞추어 비즈니스 프로세스, 종속성 및 상호 작용을 파악하고, DDD 원칙을 구현하며 시스템 설계를 비즈니스 목표에 맞추기 위한 기반을 제공한다.[12][13]

5. 마이크로서비스 아키텍처와의 관계

DDD의 기본 개념인 바운디드 컨텍스트는 도메인 모델이 일관되고 유효하며, 명확성과 관심사 분리를 보장하는 특정 영역을 정의한다.[15] 마이크로서비스 아키텍처에서 바운디드 컨텍스트는 종종 마이크로서비스에 매핑되지만, 이러한 관계는 설계 접근 방식에 따라 달라질 수 있다. 각 바운디드 컨텍스트가 단일 마이크로서비스로 구현되는 일대일 관계는 명확한 경계를 유지하고, 결합도를 줄이며, 독립적인 배포 및 확장을 가능하게 하므로 일반적으로 이상적이다. 그러나 다른 매핑도 적절할 수 있다. 바운디드 컨텍스트를 다양한 확장성 또는 기타 운영 요구 사항을 해결하기 위해 여러 마이크로서비스로 분할할 때 일대다 관계가 발생할 수 있으며, 단순화 또는 운영 오버헤드를 최소화하기 위해 여러 바운디드 컨텍스트를 단일 마이크로서비스로 통합할 수 있는 다대일 관계도 발생할 수 있다. 관계 선택은 시스템의 비즈니스 목표, 기술적 제약 및 운영 요구 사항과 함께 DDD 원칙의 균형을 맞춰야 한다.[16]

6. 도구

DDD는 특정 도구나 프레임워크에 의존하지 않지만, DDD를 지원하는 다양한 도구들이 존재한다.


  • 액티브소스(Actifsource): 이클립스 플러그인으로, DDD를 모델 기반 엔지니어링 및 자동 프로그래밍과 결합한 소프트웨어 개발을 가능하게 한다.
  • 컨텍스트 매퍼(Context Mapper): 전략적 및 전술적 DDD를 위한 도메인 특화 언어 및 도구이다.[17]
  • 큐빅웹(CubicWeb): 데이터 모델에 의해 완전히 구동되는 오픈 소스 시맨틱 웹 프레임워크이다. 데이터 모델을 정의하는 것만으로도 작동하는 웹 애플리케이션을 얻을 수 있다.
  • 오픈MDX(OpenMDX): Java SE, Java EE, 및 .NET을 지원하는 오픈 소스, Java 기반 MDA 프레임워크이다.
  • RESTful 객체(Restful Objects): 도메인 객체 모델에 RESTful API를 매핑하기 위한 표준이다. Java와 .NET용 오픈 소스 프레임워크가 존재한다.


DDD 방법론을 지원하는 주요 오픈 소스 도구 및 프레임워크는 다음과 같다.

  • Castle Windsor/MicroKernel[42]: 마이크로소프트(Microsoft)의 .NET Framework용 제어 반전 / 의존성 주입 컨테이너.
  • Cosmos[43]: 도메인 주도 설계, 특히 AOP의 실천을 지원하는 애플리케이션 프레임워크.
  • DataObjects.Net: 객체 관계 매핑과 도메인 주도 설계를 지원하는 데이터베이스 애플리케이션 프레임워크.
  • Domdrides[44]: Java로 도메인 주도 설계를 구현할 때 유용한 라이브러리.
  • ECO: CapableObjects사[45]에 의한 UML 다이어그램에서 데이터베이스, 코드, 상태 머신을 생성하는 프레임워크.
  • Flow[46]: PHP의 애플리케이션 프레임워크. 의존성 주입, AOP 프레임워크를 제공한다.
  • Habanero.NET(Habanero): .NET Framework에서 구현된 엔터프라이즈 애플리케이션 프레임워크.
  • ManyDesigns_Portofino: 오픈 소스 모델 주도형 웹 애플리케이션 프레임워크.
  • NakedObjectsFramework[47], Apache Isis[48]: 네이키드 오브젝트 패턴을 구현하고 있으며, 의존성 주입을 지원.
  • NReco[49]: 경량 오픈 소스 .NET용 도메인 고유 MDD를 수행하는 프레임워크.
  • OpenMDX: Jakarta EE, .NET을 지원하는 오픈 소스 Java용 MDA 프레임워크.
  • OpenXava: JPA 엔티티에서 Ajax 애플리케이션을 생성.
  • Roma Meta Framework[50]: 도메인 주도 설계를 중심으로 한 프레임워크.
  • Sculptor[51]: 도메인 주도 설계의 용어를 사용하는 코드 생성 프레임워크.
  • Sculpture - Model Your Life[52]: 오픈 소스 모델 주도 개발 코드 생성 도구.
  • Strandz[53]: 도메인 주도 프레임워크.
  • TrueView for .NET[54]: 모델 주도 개발과 네이키드 오브젝트를 지원하는 프레임워크.
  • ASP.NET Boilerplate[55]: 도메인 주도 설계의 웹 애플리케이션 작성 프레임워크.

참조

[1] 서적 Patterns, Principles, and Practices of Domain-Driven Design Wrox 2015
[2] 서적 Implementing Domain-Driven Design Addison-Wesley 2013
[3] 서적 Domain-Driven Design: Tackling Complexity in the Heart of Software Addison-Wesley Professional
[4] 웹사이트 Using tactical DDD to design microservices - Azure Architecture Center https://learn.micros[...] 2024-09-07
[5] 문서 Microsoft Application Architecture Guide, 2nd Edition http://msdn.microsof[...]
[6] 서적 Domain-Driven Design: Tackling Complexity in the Heart of Software http://dddcommunity.[...] Addison-Wesley 2003-08-22
[7] 서적 Serverless Architectures on AWS Manning
[8] 서적 Domain-Driven Design Reference: Definitions and Pattern Summaries
[9] 간행물 Domain-Driven Design using Naked Objects http://www.pragprog.[...] Pragmatic Programmers
[10] 문서 MDE can be regarded as a superset of MDA https://modeling-lan[...]
[11] 웹사이트 Comparing Domain-Driven Design with Model-Driven Engineering https://modeling-lan[...] 2017-09-11
[12] 서적 Learning Domain-Driven Design: Aligning Software Architecture and Business Strategy
[13] 서적 Open Agile ArchitectureTM - A Standard of The Open Group
[14] 문서 a MS bug finding tool https://www.microsof[...]
[15] 서적 Fundamentals of Software Architecture: An Engineering Approach O'Reilly Media
[16] 서적 Building Microservices by Sam Newman
[17] 논문 Domain-driven Service Design - Context Modeling, Model Refactoring and Contract Generation https://contextmappe[...] 14th Symposium and Summer School On Service-Oriented Computing (SommerSoC 2020)
[18] 서적 Patterns, Principles, and Practices of Domain-Driven Design Wrox 2015
[19] 웹사이트 bliki: Domain Driven Design https://martinfowler[...] 2024-09-04
[20] 웹사이트 Chapter 3: Architectural Patterns and Styles https://learn.micros[...] 2010-01-14
[21] 서적 Implementing Domain-Driven Design Addison-Wesley 2013
[22] Youtube What is DDD - Eric Evans - DDD Europe 2019 https://www.youtube.[...] 2019-12-21
[23] 서적 Domain-Driven Design: Tackling Complexity in the Heart of Software http://dddcommunity.[...] Addison-Wesley
[24] 서적 ドメイン駆動設計をはじめよう 株式会社オライリー・ジャパン 2024-07-18
[25] 웹사이트 bliki: Ubiquitous Language https://martinfowler[...] 2024-08-27
[26] 웹사이트 bliki: Bounded Context https://martinfowler[...] 2024-09-04
[27] 웹사이트 Using tactical DDD to design microservices - Azure Architecture Center https://learn.micros[...] 2024-09-07
[28] 웹사이트 CQRS – Simple architecture {{!}} Kariera Future Processing https://kariera.futu[...] 2015-04-10
[29] 웹사이트 戦略的設計入門 https://digitalsoul.[...] 2011-04-10
[30] 웹사이트 Transaction Script https://martinfowler[...] 2024-09-04
[31] 웹사이트 Active Record https://www.martinfo[...] 2024-09-06
[32] 웹사이트 Active Recordとは?その基礎と重要性を解説 {{!}} 株式会社一創 https://www.issoh.co[...] 2024-07-03
[33] 웹사이트 Rails/Laravel使いに送るドメインモデル~アクティブレコードの功罪~ https://qiita.com/m-[...] 2020-02-09
[34] 웹사이트 Domain Model https://www.martinfo[...] 2024-09-04
[35] 웹사이트 ドメインモデル貧血症について質問したいです。{{!}}新たな発想を生み出す質問箱 Querie.me https://querie.me/an[...] 2024-09-04
[36] 웹사이트 CQRS – Simple architecture https://kariera.futu[...] 2015-04-10
[37] 웹사이트 3層アーキテクチャーとは https://www.ibm.com/[...] 2023-03-21
[38] 웹사이트 Clean Coder Blog https://blog.cleanco[...] 2024-09-07
[39] 웹사이트 インフラストラクチャの永続レイヤーの設計 - .NET https://learn.micros[...] 2023-03-29
[40] 웹사이트 DDDを実践するための手引き(リポジトリパターン編) https://zenn.dev/koh[...] 2024-09-06
[41] 서적 Domain-Driven Design using Naked Objects http://www.pragprog.[...] Pragmatic Programmers 2009
[42] 웹사이트 Castle Project https://www.castlepr[...] 2022-08-23
[43] 웹사이트 Microsoft – Cloud, Computers, Apps & Gaming https://www.microsof[...] 2022-08-23
[44] 웹사이트 Domdrides - Overview http://domdrides.sou[...] 2022-08-23
[45] 웹사이트 CapableObjects https://www.capableo[...] 2022-08-23
[46] 웹사이트 Home https://flow.neos.io[...] 2022-08-23
[47] 간행물 Naked Objects https://github.com/N[...] Naked Objects Group Ltd 2022-07-30
[48] 웹사이트 Apache Isis https://isis.apache.[...] 2022-08-23
[49] 웹사이트 NReco: .NET REusable COmponents https://www.nrecosit[...] 2022-08-23
[50] 웹사이트 Roma Framework: The new way to conceive Web Applications https://www.romafram[...] 2022-08-23
[51] 웹사이트 Sculptor - Generating Java code from DDD-inspired textual DSL http://sculptorgener[...] 2022-08-23
[52] 웹사이트 Dawilasoft - Sculpture http://www.dawliasof[...] 2012-04-22
[53] 웹사이트 Standz http://www.strandz.o[...] 2016-10-28
[54] 웹사이트 TrueView for .NET https://evolving-sof[...] 2022-08-23
[55] 웹사이트 AspNet Boilerplate - Web Application Framework https://aspnetboiler[...] 2022-08-23
[56] 서적 Patterns, Principles, and Practices of Domain-Driven Design Wrox 2015
[57] 인용 http://www.domaindri[...]
[58] 문서 Microsoft Application Architecture Guide, 2nd Edition http://msdn.microsof[...]
[59] 서적 Domain-Driven Design: Tackling Complexity in the Heart of Software http://dddcommunity.[...] Addison-Wesley 2012-08-12



본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.

문의하기 : help@durumis.com