DDD (Domain-Driven Design)
DDD란?
DDD란? 소프트웨어 개발 전체 LifeCycle에서 도메인 중심의 사고를 장려하는 소프트웨어 개발 철학
도메인은 특정 분야의 비즈니스라고 볼 수도 있는데,
비즈니스 관점으로 소프트웨어 구조를 설계해보자는 패러다임(?)이라고 생각하면 쉬울 것 같습니다.
예시로 A호텔에서 IT회사인 B테크 회사에게 호텔 예약 플랫폼 개발 사업을 발주했다고 가정해보겠습니다.
기존대로라면 B테크 회사는 대중적으로 활용되었던 폭포수 모델을 활용하여 플랫폼 개발에 나설거에요.
요구사항 수집 -> 설계 -> 개발...
여기서 B테크는 고객의 요구사항을 데이터 및 시스템 중심으로 설계하여 개발을 진행합니다.
B테크는 고객의 요구사항을 데이터 및 시스템 관점으로 설계해야 하는 다소 까다로운 과정을 거치게 되고,
고객의 요구사항이 긴급하게 바뀌었을 때는 해당 과정을 다시 진행해야 하기 때문에 유연하게 대처하기 힘듭니다.
하지만 B테크가 DDD를 적용한다면?
- 도메인(비즈니스) 지식 중심으로 해당 비즈니스 종사자와 설계를 같이 진행하기 때문에 설계과정을 보다 쉽게 진행할 수 있고,
- 도메인 중심으로 코드 구조를 짜고 작성하기 때문에 요구사항이 변경되어도 유연하게 대처할 수 있습니다.
DDD 적용 규칙
위에서 언급한 DDD의 장점을 누리기 위해서는 비즈니스 종사자와 개발자가 코드 기반으로 원할한 소통이 보장되어야 합니다.
이를 위해 아래의 규칙이 준수되어야 하죠.
1. 유비쿼터스 언어 사용
: 비즈니스 종사자와 개발자가 모두 이해할 수 있는 네이밍을 활용해야 합니다. (ex. create_reservation -> make_reservation)
2. 다른 도메인간 언어 통일을 강요하지 않습니다.
: 다른 도메인간 언어 통일이 되었을 때, 오히려 혼란을 야기할 수 있습니다.
3. 코드 구조를 추상화하여 비즈니스 종사자가 쉽게 이해할 수 있도록 합니다.
AS-IS
public void createReservation(User user, Seat seat, LocalDateTime startTime, LocalDateTime endTime){ Reservation reservation = new Reservation(); reservation.setUserId(user.id); reservation.setSeatId(seat.id); reservation.setStartTime(startTime); reservtiion.setEndTime(endTime); this.reservationRepository.save(reservation); }
TO-BE
public void makeReservation(User user, Seat seat, LocalDateTime startTime, LocalDateTime endTime){ this.reservationCommandService .makeReservation(user, seat, startTime, endTime); }
DDD in MSA
MSA개요는 👉MSA개요 글 참고
위와 같은 DDD 적용 규칙은 모놀리스 아키텍처보다 MSA에서 더 쉽게 적용될 수 있습니다.
모놀리스에서는 다른 도메인간 언어 통일이 필요하다는 등의 이유가 있기 때문이에요.
그렇기 때문에 DDD는 MSA에서 많이 활용되고 있는 방법론입니다.
DDD를 MSA에 적용한다고 했을 때,
- 서비스를 얼마나 쪼갤지?
- 쪼갠 도메인간 어떻게 연동할 것인지?
에 대해 추가적으로 검토되어야 합니다.
서비스를 분해하는 방법
서비스를 얼마나 분해할 지에 대해서는 아래 기준을 고려하여 결정합니다.
- 서비스 복잡도 : 서비스를 쪼갤수록 야기되는 서비스 구현 및 운영 복잡도
- 비즈니스 차별성 : 서비스를 쪼갰을 때, 취할 수 있는 비즈니스 및 비용 관점의 이점
도메인간 연동하는 방법
도메인을 어떻게 연동할 지에 대해서는
- 도메인간 연관성이 얼마나 높은지?
- 도메인의 중요도가 어떻게 되는지?
에 따라 달라집니다.
연관성 및 중요도가 높을 수록 아래 우선순위대로 연동방식을 고려해야 합니다.
- shared DB : 도메인간 DB를 공유
- req-res 구조의 동기식 연동 방식 : 타도메인의 연동에 대한 응답을 기다림
- pub-sub 구조의 비동기식 연동 방식 : 타도메인의 연동에 대한 응답을 기다리지 않음
Event Storming
Event Storming 이란?
Event Storming이란? 시스템에서 발생하는 이벤트 중심으로 분석 및 설계하는 기법으로 MSA 기반의 도메인에 대한 빠른 이해를 도모
전통적 방식에서 진행하던 UML 및 ERD 설계 대신에 비즈니스 종사자와 함께 진행하는 과정으로 보면 됩니다.
Event Storming 방법
준비
- 참석자
- PO(업무전문가, 비즈니스 종사자)
- Front-End 개발자
- Back-End 개발자
- 퍼실리테이터 (Event Storming 전문가, Optional)
- 준비 도구
- 벽이 넓은 공간 (Ex. 넓은 화이트보드 등)
- 여러 색의 포스트잇
- 검은색 보드마카
- 파란색 테이프
진행
포스트잇 유형
방법 : 아래 언급된 순서에 맞게 포스트잇을 겹쳐 붙이는 방식, 연동의 경우는 선으로 연결, 분리된 도메인은 Bounded Context로서 분리 표시
순서
- Event 발굴 : 비즈니스에서 발생할 수 있는 Event를 발굴
- 오렌지색 포스트잇 활용
- 동사의 과거형으로 네이밍 (유비쿼터스 언어, Ex. Account Created)
- Command 도출 : 이벤트를 초래하는 페르소나(사용자or시스템)의 동작을 도출
- 파란색 포스트잇 활용
- 동사원형으로 네이밍 (유비쿼터스 언어, Ex. Create Account)
- 초래되는 이벤트의 왼쪽에 겹쳐 붙임
- 데이터에 변화를 일으킬 수 있는 동작 위주로 도출 (CRUD중 CUD case)
- Actor 도출 : 특정 Command를 수행하는 주체를 결정
- 노란색 포스트잇 활용
- 명사로 네이밍 (유비쿼터스 언어, Ex. Customer)
- 수행하는 Command의 왼쪽에 겹쳐 붙임
- Policy 도출 : 특정 이벤트가 발생했을 때, 연쇄적으로 발생하는 동작을 도출
- 분홍색 포스트잇 활용
- Command와 동일하게 동사원형으로 네이밍 (유비쿼터스 언어, Ex. Send Email)
- Command와 동일하게 초래되는 이벤트의 왼쪽에 겹쳐 붙임
- 데이터에 변화를 일으킬 수 있는 동작 위주로 도출 (CRUD중 CUD case)
- Aggregate 도출 : 같은 Entity를 사용하는 연관 도메인 이벤트들의 집합 도출
- 노란색 포스트잇 활용
- 명사로 네이밍 (유비쿼터스 언어, Ex. Account Mgmt)
- Command와 Event 사이에 겹쳐 붙임 (Command와 Event가 겹쳐 붙어있는 경우, 분리하여 사이에 붙임)
- 하나의 트랜잭션으로 동작이 필요할 경우, 하나의 Aggregate로 묶음
- Bounded Context 도출 : 효율적으로 업무 용어를 사용할 수 있는 도메인별 범위로 분리
- 분리방식 결정 (Domain별 or Transaction별 or Tech Stack별 등)
- Bounded Context로 Micro Service를 구성한다면 효율적 커뮤니케이션이 가능함
- Context Mapping : Aggregate간 연동방향 및 방식 결정
- Event와 Command의 연결 : req-res 연동 방식
- Event와 Policy의 연결 : pub-sub 연동 방식
- 기타
- 특정 포스트잇에 대한 질문이 있는 경우, 보라색 포스트잇에 작성하여 문의의 포스트잇에 삐뚤게 붙임 -> 문의를 해결한 경우, 반듯이 고쳐 붙임
- 결과
Next
다음 글은 MSA 구현에 대해 살펴보겠습니다.
Reference
- 사내 강의 (Microservice Modeling) - 박용주 강사님
- DDD란 무엇인가 - 데이터 중심 개발과 도메인 중심 개발 : https://appleg1226.tistory.com/40
'개발 > MSA' 카테고리의 다른 글
[MSA] API Gateway와 Circuit Breaker (0) | 2024.11.07 |
---|---|
[MSA] 헥사고날 아키텍처와 MSA 전환 (0) | 2024.11.03 |
[k8s] kubernetes 클러스터 (1) | 2024.04.06 |
[k8s] kubernetes란? (0) | 2024.02.29 |
[MSA] MSA (Microservices Architecture) 표준 아키텍처 (0) | 2024.02.15 |