최근 유튜브를 통해 다양한 기술 관련 내용을 보고 있던 중, 알고리즘이 DDD(Domain-Driven Design) 관련 영상을 추천해 주었다.
DDD를 처음 접한 것은 오래전 회사의 다른 부서 팀원과 솔루션 개발 방향에 대해 이야기하던 중이었는데, 당시에는 개발방법론으로서 DDD를 접했지만, 자세히 알지 못해 여러 아티클을 찾아보았던 기억이 난다.
당시에는 단순히 논리적인 영역에서 도메인을 나누어 개발하는 것으로만 이해했었고, 이는 이미 많은 개발자들이 자연스럽게 사용하는 방법론이라고 생각했었다.
하지만 이번에 유튜브에서 본 영상을 통해 DDD의 주요 포인트를 다시 생각해 보게 되었고, 이를 정확히 이해할 수 있었다. 이 영상은 DDD를 명확하게 설명해 주는 아주 좋은 자료라고 생각되어 그 내용을 정리해보고자 한다.
DDD 뭣이 중헌디?
DDD에 대한 오해
DDD는 전술적 패턴이다 (X)
- 중요한 부분은 전략적 설계
- 너무 전술적 설계에 함몰되지 말자
- 즉, 큰 그림을 잘 그리는 것이 중요
DDD는 은탄환이다 (X)
- 만병 통치약이 아니다
- 단순한 소프트웨어나 비즈니스 도메인 요소가 약한 서비스에도 어울리지 않는다
DDD는 MSA로 귀결된다. (X)
- 두 개를 아예 세트로 묶는 경우도 많은데, 주의해야 할 필요가 있다고 생각합니다.
- 시너지가 날 수는 있는데 무조건적이진 않다.
DDD는 기술이나 구현 영역이다. (X)
- 전술적 패턴에 함몰된 방법
Domain Driven Design
패턴 사용법, 관례, 방법론으로 인식하지 말자.
DDD는 추상적인 철학이나 접근법이 그 본질이다.
그 본질은 전략적 설계에 근간을 두고 있다.
전략적 설계
도메인
비즈니스 도메인과 문제 도메인
비즈니스 도메인
- 현실 세계의 주요 활동 영역, 즉 회사가 고객에게 제공하는 서비스 영역
문제 도메인
- 회사가 비즈니스 도메인의 일부 영역을 소프트웨어를 통해 해결하고자 할 때, 그 영역을 문제 도메인이라고 부른다.
- 즉 소프트웨어로 어떤 문제를 해결하여서 가치를 창출하는지가 시작점.
- 특정 회사는 문제 도메인과 비즈니스 도메인이 같을 수도 있다!
문제 공간
문제 공간을 인식하는 게 아니라 하위 도메인(서브도메인)으로 나누는 것까지 가야 한다.
- 비즈니스 모델은 복잡하고 방대해서 나누고 정복하는 것이 편하기 때문 (분할 정복)
도메인 전문가와 최초 개발자가 의사소통을 통해서 지식 탐구(놀리지 크런치)가 계속 진행되어야 한다.
핵심 하위 도메인, 일반 하위 도메인, 지원 하위 도메인 식별 (전략적 설계에서 문제 공간까지 확보)
- 증류 또는 추출
- 중요한 것과 중요하지 않은 것을 나눈다
하위 도메인 유형 | 경쟁 우위 | 복잡성 | 변동성 | 구현 | 난이도 |
핵심 | 😃 | 최상 | 상 | in-house | 최상 |
일반 | 상 | 하 | 솔루션 구매 | 상 | |
지원 | 하 | 하 | in-house, 하청 | 하 |
해결공간
해결 공간에서의 지식 탐구는 개발자가 추가된다.
- 개발영역에 설계가 시작되기 때문에
하위 도메인에서 바운디드 컨텍스트를 식별하고, 바운디드 컨텍스트가 관계와 전술까지 선택
브라운 필드 전략적 설계
에반스의 표현으로 비추어 보면 현실에서 90퍼 이상 브라운 필드 상황.
- 브라운 필드: 이미 구축된 소프트웨어에서 진행하는 프로젝트
- 그린 필드: 이에 반대되는 신규 프로젝트
애초에 소프트웨어가 얼마나 복잡해질지 모르는 상황에서 DDD를 처음부터 적용하는 것은 도움이 되지 않는 경우가 많다.
- DDD는 은탄환(만병통치약)이 아니기 때문
소프트웨어의 기능이 추가되며 모델과 관계가 증가하여 복잡해진다.
Big Ball of Mud
- 특별한 구조가 없는 아키텍처 스타일
- 단순한 소프트웨어는 빅볼오브머드 스타일로도 충분히 구현이 가능하다. → 안티 패턴이 아니라 선택할 수 있는 전술 중 하나다.
이러한 시점에 DDD를 적용하여 개선하면 효과가 좋다.
전략적 설계 시 유용한 도구
- 사용 사례 분석
- 탑다운 방식
- 이벤트 스토밍
- 브라운 프로젝트 상황에서 매우 유용
- 구현 모델에서 도메인 지식을 복구할 때도 유용한 기법
- 도메인 이벤트라는 구체적인 것에서 추상적인 바운디드 컨텍스트로 나누는 바텀업 방식
- 비즈니스 모델 분석
- 비즈니스 모델의 핵심 전력이나 수익 모델에서 시작하는 방법
중요한 건 언제 어디서나 도메인 문맥 내에서 유비쿼터스 언어로 소통하자.
전략적 설계 vs 전술적 설계
설계 | 전략적 설계 | 전술적 설계 |
범위 | 전반적 | 특정 Bounded-Context |
목적 | 문제 도메인을 해결영역으로 | 풍부한 도메인 모델 적용 |
메타포 | 전쟁에서 전략 | 전투에서 전술 |
주요 패턴 | Bounded-Context, Ubiquitous-Language | Aggreagte, Domain-Event |
수행 방식 | 접근법 | 상대적으로 방법론에 가까움 |
전략적 설계 과정
문제 공간을 해결 공간으로
Bounded-Context
경계가 있는 문맥
경계: 해결 공간에서 모델의 경계
경계를 명확하게 판단하려면?
- 유비 쿼터스 언어가 무엇보다 중요.
- 바운디드 컨텍스트가 다르면 유비 쿼터스 언어도 달라진다.
- 즉, 바운디드 컨텍스트는 유비쿼터스 언어와 함께 모델의 무결성을 위한 경계
모델 무결성
- 이름은 같은데 다른 개념
- Ex)
- 문맥: 회원, 모델: Account - 회원 계정
- 문맥: 은행, 모델: Account - 은행 계좌
- 문맥 내에서는 언어가 확실해진다.
- Ex)
- 동일한 개념모델이지만 여러 문맥에 의존하는 경우
- 모든 컨텍스트의 요구 사항을 만족하려면 프로덕트 모델은 매우 복잡해진다.
- 이런 경우, 컨텍스트 별로 필요한 기능을 수행하는 모델이면 충분
- Ex)
- 문맥: 예외, 모델: Product - [예매 가능?(), 할인 가능?()]
- 문맥: 정산, 모델: Product - [상품 가격, 정산 대상?()]
- 문맥: 상품 & 스케줄, 모델: Product - [상품 상세 정보, 상품 분류, 회차 정보, 예매자에게 노출하는 상품인가?()]
- 두 개의 바운디드 컨텍스트를 하나로 합치는 해결 공간의 변경이 일어남.
- 상품 ← 상품 & 스케줄
- 합쳐지는 것뿐 아니라, 분리되는 경우도 발생할 수 있음
- 두 개의 바운디드 컨텍스트를 하나로 합치는 해결 공간의 변경이 일어남.
- 모든 컨텍스트의 요구 사항을 만족하려면 프로덕트 모델은 매우 복잡해진다.
Bounded-Context와 하위 도메인
하위 도메인과 바운디드 컨텍스트는 일종의 집합 관계가 되지만, 해결 공간을 찾을 때 다양한 상황이 발생.
- 해결 공간을 표현할 때, 하나의 하위 도메인의 바운디드 컨텍스트가 보통 한 개 이상 존재할 수 있음
- 이것이 하위 도메인과 바운디드 컨텍스트의 일반적인 관계
- 1:1의 관계를 가질 때도 있고, 여러 개의 하위 도메인을 포함일 수 도 있다.
바운디드 컨텍스트가 여러 개의 하위 도메인을 포함하는 경우도 있는데, 일반적으로 기존의 레거시 컨텍스트가 복수개의 하위 도메인을 가지는 경우가 많다
- DDD의 전략적 설계를 적용해서, 구조가 바뀌고 있는 과도기 or 어쩔 수 없이 기술 부채를 가지고 가는 상황
해결 공간에서 각 바운디드 컨텍스트 별로 전술을 선택하는 것도 중요하다.
- 핵심 도메인 선정 후, 개발 역량 집중을 위한 전략적 설계를 위함 (Model-Driven)
- 일반 도메인, 지원 도메인 등은 서드파티 솔루션을 구매하거나, 아웃소싱을 통해 개발 리소스를 절약하는 것도 전략
콘웨이의 법칙
바운디드 컨텍스트를 아무리 나누어도 소프트웨어 개선이 원활하지 않는 법칙
- 소프트웨어의 구조는 해당 소프트웨어를 개발하려는 조직의 구조를 따라가는 법칙
- 증명되지는 않음, 이름만 법칙
- 일종의 현상, 상황으로 이해
역콘웨이의 전략
소프트웨어의 성공을 위한 전략
- 개발하는 구조를 소프트웨어의 구조에 맞춘다
- 유기적인 협업 촉진
Context-Map
Bounded-Context와 매핑 관계를 그린 다이어그램
- 서브 도메인 별 Bounded-Context 나누고, Context별로 의존, 통합 필요시 화살표, 선을 통한 매핑 관계 설정
Bounded-Context 매핑 관계
매핑 관계는 컴포넌트나 솔루션 조직 구조, 특히 정치적인 상황에 따라서 많이 달라진다.
매핑 관계 | 설명 | 추가정보 |
부패 방지 계층(ACL) | 도메인 모델의 부패(손상)을 방지하는 계층 | 외부 의존 모델을 번역해서 도메인 모델로 |
공유 커널(SC) | 두 컨텍스트가 공통의 Context를 공유해서 사용 | 긴밀한 팀에서 적용 가능 |
오픈 호스트 서비스(OHS) | 공급자 Context에서 소비자 Context에 맞게 모델 제공 | 일반적으로 공표된 언어(PL)로 제공 |
분리형 노선(SW) | 각각 모델을 관리 | 중복 발생 |
파트너십(P) | 두 팀이 최대한 협력 | 매우 긴밀한 팀에서 적용 가능, 공유 커널 |
고객/공급자(C/S) | 공급자는 고객의 요구에 가능한 들어줘야 한다. | 갑: 소비자 Context, 을: 공급자 Context |
순응자(Conformist) | 고객은 공급자(외부 솔루션, 레거시 등)가 주는 대로 사용해야 한다. | 갑: 공급자 Context, 을: 소비자 Context |
비동기 이벤트(Async) | 메시지 브로커를 통한 비동기 통합 | 개발 난이도 상승, 결과적 일관성 |
EX) 솔루션을 사용할 경우, 어쩔 수 없이 순응자 패턴을 사용할 수 밖에 없어진다.
- 하지만 솔루션 회사 자체를 구매하면 고객/공급자 패턴으로 변경된다.
Context-Map
위 단계들을 적용한 Context-Map
세줄 요약
- DDD에서 전략적 설계가 중요하다
- 지식 탐구와 커뮤니케이션
- 언제 어디서나 유비쿼터스 언어로 소통
'Programming' 카테고리의 다른 글
LLM을 사용한 AI 코드 리뷰 이야기 - NAVER Engineering day 2024 (0) | 2024.07.28 |
---|---|
JDK Vender 확인 명령어 (0) | 2021.03.17 |
Json 타입별 간편 Convert(ObjectMapper) (0) | 2021.03.15 |
JAVA - Classpatch 지정 시 오류 발생 해결법 (0) | 2020.08.18 |
C언어 - 분기문 (goto, break, continue, return) (0) | 2020.06.24 |