도메인 주도 설계의 개념
은총알은 없다.
“은총알은 없다.”
- 모든 문제를 단번에 완벽하게 해결해주는 단순하고 완벽한 해법은 존재하지 않는다.
- 소프트웨어는 0과 1로 개발되지만, 이것이 다루는 현실 세계의 문제는 복잡하고 변화한다.
- 따라서 완벽한 소프트웨어 설계란 것은 불가능하다.
- 현실 문제의 복잡성과 변화에 맞서 싸우기 보다는, 그것들을 프로세스에 내재화 하는 게 적절.
- 이러한 관점에서 접근하는 설계 기법이 바로 DDD
한 마디로
복잡하고 변화하는 비즈니스 문제를
도메인 중심의 모델링과 협업으로 해결하는 설계 철학
언제 적용할까?
어울리는 경우
- 복잡한 비즈니스 로직을 가진 도메인을 다룰 때.
- 도메인 전문가와의 협업이 필수적인 프로젝트.
- 지속적인 변화, 확장이 예상되는 시스템
어울리지 않는 경우
- 매우 단순한 CRUD 애플리케이션
- 단기성 프로젝트나 프로토타입
- 도메인 지식이 부족하거나 전문가와 협업이 어려운 환경.
단계적 접근 방법
(1) 초기에 서비스/도메인/저장소 구조만 간단히 분리
(2) 복잡도가 증가할 때 애그리거트, 밸류 오브젝트, 도메인 이벤트 적용
(3) 서비스 경계를 나누는 단계에서 Bounded Context 명확화
특징
- 구현 기술보다 “비즈니스 개념(도메인)”을 중심으로 설계한다.
- “어떻게 구현할까?” 보다 “무엇을 표현할 것인가?” 에 초점을 맞춘다.
- 예시:
Order
,Payment
,Scheduler
등 실존 개념이 클래스나 메서드로 표현된다. - 도메인 개념과 코드 구조가 1 대 1로 대응되는 것을 이상적으로 본다.
- 즉, 소프트웨어 엔티티와 도메인간 개념이 일치하는 것을 이상적으로 본다.
주요 개념
용어 | 설명 |
---|---|
도메인 Domain |
- 소프트웨어로 해결하고자 하는 문제 영역 - 예) 쇼핑몰을 구축할 때 도메인은 전자상거래 |
도메인 모델 Domain Model |
- 특정 도메인을 이해하고 표현하기 위한 개념적 모델 - 이후 구현 모델을 만들 때, 개념 모델을 최대한 따르도록 설계할 수 있다. |
유비쿼터스 언어 Ubiquitous Language |
- 개발과 비즈니스 커뮤니케이션 전반에서 - 프로젝트에 관여된 모든 사람들이 공통으로 사용하는 언어 - 팀원 간 의사소통 원활케 하고 도메인 이해 높이는 효과 |
바운디드 컨텍스트 Bounded Context |
- 도메인을 명확하게 구분 짓는 경계 - 각 바운디드 컨텍스트는 독립적으로 개발되고 배포될 수 있음 - 서로 다른 바운디드 컨텍스트 간 상호작용은 명확한 인터페이스를 통함 |
애그리거트 Aggregate |
- 도메인 모델 일관성 유지를 위해 관련된 객체들을 묶어 관리하는 단위 - 하나의 루트 엔티티 (aggregate root)를 가진다 - 외부에서는 루트 엔티티를 통해서만 접근할 수 있음 |
엔티티 Entity |
- 고유한 식별자를 가지고, 상태와 행동을 갖는 객체 |
밸류오브젝트 Value Object |
- 고유한 식별자를 가지지 않으며, - 불변성을 가지는 객체 - 도메인 모델의 속성을 표현하는 데 사용됨. |
도메인이란
도메인
사전적 의미
an area of interest or an area over which a person has 관심 영역 또는 개인이 통제권을 가진 영역
- 도메인의 어원은 1600년 경 프랑스에서 “지배 영역, 활동 범위” 의미로 사용된 domaine
- 이후 누군가가 통제하거나 영향을 미치는 활동 또는 관심 분야의 의미로도 확장되었다.
소프트웨어 개발에서의 도메인이란
소프트웨어로 해결하고자 하는 문제 영역
- 실세계에 존재하는 비즈니스 영역으로, 소프트웨어로 구현해야 할 대상
- 쇼핑몰을 구축할 때 도메인은 전자상거래이며, 개발을 위해선 이에 대한 지식을 쌓아야 한다.
하위 도메인
개념
- 도메인이 클 경우, 여러 하위 도메인(Subdomain)으로 나눌 수 있다.
- 하위 도메인 중 일부는 외부 시스템을 사용하기도 한다.
분류
- (1) 핵심 도메인(Core Subdomain) : 비즈니스 경쟁력을 결정짓는 핵심
- (2) 지원 도메인(Supporting Subdomain) : 핵심 도메인을 지원하는 역할
- (3) 일반 도메인(Generic Subdomain) : 범용적이고 특별한 차별성이 없는 도메인
하위 도메인을 나눌 때, 각 하위 도메인들의 중요성에 따라 나누는 게 중요
이를 통해 자원(인력, 자본)의 분배와 효율적인 포커싱을 할 수 있다.
“어디에서 돈을 버는가”, “우리의 비전은 무엇인가” 등의 판단기준을 세우면 분류가 편하다.
핵심 도메인은, 향후 상황에 따라 변경될 수도 있다.
예시
- 전자상거래 도메인의 경우 산품, 전시, 주문, 결제, 정산 등.
도메인 모델
정의
- 특정 도메인을 개념적으로 표현한 것.
- 기본적으로 도메인 자체를 이해하기 위한 개념 모델.
- 이후 구현 모델을 만들 때, 개념 모델을 최대한 따르도록 설계할 수 있다.
도메인 모델 만들 때
- 요구사항 분석을 통해 도메인을 이해하고, 이를 바탕으로 도메인 모델 초안을 만든다.
- 도메인이 제공하는 기능과 도메인의 주요 데이터 구성을 파악해야 함
- 각 도메인의 특성을 잘 표현할 수 있는 표현 방법을 선택하는 게 중요.
- 객체 모델은 기능과 데이터를 함께 보여주기 때문에 모델링에 적합함
- 상태 다이어그램의 경우, 비즈니스의 흐름을 볼 수 있다는 장점이 있음
- 이외에 계산 규칙이 중요하다면 수학 공식을 활용하거나..
예시
- 전자상거래 도메인의 도메인 모델
유비쿼터스 언어
유비쿼터스 Ubiquitous
- 과거, 신에 대해 표현할 때 언제 어디서나 존재하는 라는 의미로 사용된 단어
- 오늘날에는
유비쿼터스 언어의 정의
- 개발자, 도메인 전문가, 기획자 등 모든 프로젝트 참여자가 공유하는 공통 언어
- 개발과 비즈니스 커뮤니케이션 등 프로젝트 전반에서 사용되어야 함.
- 모델, 코드, 문서, 회의 등 모든 소통 수단에서 일관되게 사용될 수 있게 노력해야 함.
- 이를 통해 팀원 간 의사소통 원활케 하고 도메인 이해 높이는 효과를 줄 수 있음
유비쿼터스 언어의 필요성
- 클래스나 함수의 네이밍은 매우 중요하며, 특히 DDD 에서는 도메인 기반 네이밍이 중요
- 주용 용어는 한글과 영문을 함께 정의하고, 그것의 의미를 명확히 기록하는 것이 좋음
- 명사 뿐 아니라 동사도 포함한 용어사전을 만드는 것이 바람직
- 일반적으로는 바운디드 컨텍스트 안에서 정의함
- (초기 그린필드 상황에는 유연하게 시작해도 무방)
Bounded Context
정의
- 컨텍스트 : 문맥
- Bounded Context : 도메인과 도메인을 명확하게 구분 짓는 경계
- 각 바운디드 컨텍스트는 독립적으로 개발되고 배포될 수 있음
- 서로 다른 바운디드 컨텍스트 간 상호작용은 명확한 인터페이스를 통함
- 각 컨텍스트는 독립적인 개발, 배포의 단위가 될 수 있음.
필요성
- 현실 문제는 복잡하고 거대함 -> 모든 것을 표현하는 통일된 단일 모델을 도출하기 어려움
- 동일한 용어라도 각각의 비즈니스 영역(컨텍스트)에 따라 의미하는 바가 달라질 수 있음
- 따라서 컨텍스트의 모델이 독립적이며 일관성을 유지할 수 있도록 해야 함.
예시
- 전자 상거래 도메인 모델의 예시로
- 주문 / 배송 / 회원 관점에서의 유저는 실제로 의미하는 것이 다르다.
- 주문 관점 : 주문자를 의미함. 주문 생성과 결제의 주체. 결제 정보, 주문 이력 등이 중요.
- 배송 관점 : 수취인을 의미함. 주문된 상품을 받을 사람. 배송 주소, 연락처 등이 핵심 정보.
- 회원 관점 : 회원을 의미. 유저의 기본 정보(아이디, 비밀번호..) 등이 핵심 정보.
바운디드 컨텍스트와 서브도메인
- 서브도메인 : 비즈니스적, 문제 해결 관점에서 나눈 문제 공간.
- 바운디드 컨텍스트 : 서브도메인을 구현하는 소프트웨어 모델의 명확한 경계.
- 하나의 서브도메인이 여러 바운디드 컨텍스트로 나뉠 수 있음.
서브도메인 | 바운디드 컨텍스트 |
---|---|
- 엔진 구동 서브도메인 - 운전 제어 서브도메인 - 안전 시스템 서브도메인 - 인포테인먼트 서브도메인 |
- 안전 시스템 서브도메인 > 에어백 제어 바운디드 컨텍스트 > 운전자 보조 시스템 바운디드 컨텍스트 … |
Aggregate
정의
- 도메인 모델 일관성 유지를 위해 관련된 객체들을 묶어 관리하는 단위
- 함께 변경되는 연관 객체들의 묶음.
- 하나의 루트 엔티티 (aggregate root)를 가진다
- 외부에서는 루트 엔티티를 통해서만 접근할 수 있음
필요성
- 도메인 모델은 많은 엔티티와 객체로 복잡하게 구성될 수 있는데,
- 이들의 복잡한 상호작용 속에서 데이터의 일관성을 유지해야 한다.
- 예를 들어, 특정 객체가 변경될 때, 연관된 객체들도 함께 변경되는 일관성.
- 이러한 복잡성을 응집력 있는 하나의 단위로 묶어 관리해 일관성을 지키도록 함.
애그리거트 루트
- 애그리거트 내의 여러 개의 객체 중 하나의 엔티티를 애그리거트 루트로 삼는다.
- 애그리거트의 일관성 규칙을 책임진다.
- 해당 애그리거트로 접근하는 모든 외부 접근의 컨택 포인트가 된다.
- 즉, 애그리거트 내의 루트가 아닌 다른 객체에 직접 접근, 변경하는 것은 금지된다.
MSA와 DDD
- MSA : Micro Service Architecture
- MSA 아키텍처를 가지는 시스템을 계획하거나 모놀리식 아키텍처를 MSA로 전환할 때 DDD를 많이 사용함.
- MSA 는 “경계를 어떻게 나누느냐”가 중요하고, DDD는 “경계를 잘 나누는 방법”을 제공하기 때문
- 다만 MSA의 모든 경우에서 DDD를 채택하는 것은 아니다. 목적과 맥락에 따라 선택해야 한다.
Reference
도메인 주도 개발 시작하기 - 최범균 저
https://youtu.be/sLG5n_pXWK0?feature=shared
https://tech.kakaopay.com/post/backend-domain-driven-design/
https://medium.com/nick-tune-tech-strategy-blog/core-domain-patterns-941f89446af5
Comments