
복잡한 비즈니스를 요리하는 이벤트 스토밍과 DDD 전략
지난 포스팅에서 대수적 타입을 통해 데이터 구조를 설계하는 법을 다뤘다면, 이번에는 그 데이터를 움직이게 하는 '맥락'과 '흐름'을 설계하는 방법을 알아보겠습니다.
1. 도메인을 분석하는 이벤트 스토밍
설계의 시작은 코드가 아니라 화이트보드여야 합니다.
이벤트 스토밍은 비즈니스 이벤트를 중심으로 유저의 내러티브를 시각화하는 강력한 도구입니다.
이벤트 스토밍의 핵심 흐름
- 도메인 이벤트: 시스템에서 발생한 의미 있는 사건.
- 명령과 액터: 이벤트를 유발하는 사용자의 의도.
- 정책: "이벤트가 발생하면 ~한다"는 비즈니스 규칙.
- 읽기 모델: 사용자가 명령을 내리기 위해 참조하는 데이터.
- 애그리게이트: 명령을 처리하고 불변식을 지키는 진입점.
핵심 인사이트: 내러티브의 끝은 항상 이벤트가 아닙니다.
사용자가 다음 행동을 결정할 수 있게 정보를 제공하는 읽기 모델이 피드백 루프의 종착점이 될 수 있습니다.
2. 싸우지 않기 위한 경계, 바운디드 컨텍스트
DDD에서 가장 흔한 오해는 "모든 코드가 하나의 완벽한 모델을 공유해야 한다"는 것입니다.
하지만 실무에서는 "이 코드를 두 팀이 관리하면 싸우는가?"를 기준으로 경계를 나눠야 합니다.
- 문제 공간: 도메인을 분할한 것.
- 솔루션 공간: 실제 구현 단위인 바운디드 컨텍스트.
컨텍스트 매핑
- 충돌 방지 계층: 외부 시스템에 순응하지 않고 우리 도메인 모델을 보호하는 변환기.
- 오픈 호스트 서비스: 우리 컨텍스트를 누구나 편하게 쓸 수 있게 제공하는 표준 API.
- 분리형 노선: 아예 의존성을 끊고 각자 갈 길을 가는 것.
3. 트랜잭션 vs Saga 일관성의 전쟁
애그리게이트 내부는 즉시 정합성을 맞추는 '트랜잭션 일관성'을 지키지만, 애그리게이트 사이는 '결과적 일관성'을 선택해야 합니다.
- Saga 패턴: 분산된 애그리게이트 간의 일관성을 맞추기 위해 이벤트를 주고받으며 처리합니다.
- 보상 트랜잭션: 중간에 실패하면 이전에 처리된 작업을 취소하는 이벤트를 발행합니다.
- 프로세스 관리자: 복잡한 워크플로우를 통제하는 중앙 관리자를 두어 각 애그리게이트의 부담을 줄입니다.
4. 아키텍처와 DDD의 결합
최근 MSA와 함께 헥사고날 아키텍처가 뜨는 이유는 무엇일까요? 핵심은 애그리게이트의 격리입니다.
외부의 DB나 API 프레임워크로부터 도메인 로직을 순수하게 보호할 수 있기 때문입니다.
5. 함수형 프로그래밍
결국 견고한 DDD 구현은 함수형 프로그래밍의 원칙과 맞닿아 있습니다.
- 식별성 대신 값: ID로 객체를 찾는 대신, 상태 그 자체로 비즈니스를 연산합니다.
- 부수효과 격리: 순수 함수로 로직을 작성하고, DB 저장 등의 부수효과는 가장 바깥쪽 으로 밀어냅니다.
- 대수연산: 지난 시간에 배운 합타입/곱타입을 조합하여 도메인 규칙을 컴파일 타임에 강제합니다.
애그리게이트 격리에 도움이 되는가?
우리가 하는 모든 설계 활동의 본질은 딱 하나입니다.
"이 설계가 애그리게이트의 불변식을 보호하고 격리하는 데 도움이 되는가?"
이 질문에 답할 수 있다면, 당신은 이미 올바른 DDD의 길을 걷고 있는 것입니다.