TIL - DDD기획 항공권 예약 사이트 ContextMap , Aggregate Root 도출 (10.29)
2025. 10. 29. 23:46

📚 오늘 공부한 내용

DDD Context Map 재설계와 Aggregate Root 도출

어제에 이어 오늘은 DDD 기반 항공권 예약 시스템의 Context Map을 대폭 수정하고, Aggregate Root를 설계하는 작업을 진행했다. 특히 DDD QnA 세션을 통해 우리가 잘못 이해하고 있던 부분들을 수정하였다.

Context Map 1차 설계 및 문제점

어제 작성했던 초기 Context Map은 총 6개의 컨텍스트로 구성되어 있었다:

  • Plane Ticketing
  • Reservation
  • Payment
  • Flight
  • User
  • Mileage

이 구조에서 우리는 대부분의 관계를 Customer/Supplier로 정의했고 Plane Ticketing과 Payment에 관련해서 결제가 없으면 항공권이 존재하지 않는 긴밀한 관계라고 생각하여 Partnership이라 정의를 하였다.

아래에 아주 조금 더 자세하게 써보겠다.

DDD QnA 세션에서 배운 것

오늘 DDD QnA 시간에 우리의 Context Map이 올바른 방향으로 가고 있는지 질문했다.

솔직히 말하면 명확하게 이해하지는 못했다.

처음 해보는 작업이기도 하고 용어가 낮설며 너무 추상적이였기 때문이다.

하지만 우리가 이해한 방향은 

컨텍스트는 팀 단위로 나뉠 수 있어야 한다

컨텍스트는 단순히 엔티티나 기능 단위가 아니라, 독립적으로 운영될 수 있는 팀 단위로 나눠야 한다는 것을 깨달았다. 이는 마이크로서비스의 경계를 나누는 것과도 유사한 개념이었다.

이 원칙에 따라 우리는 6개의 컨텍스트를 3개로 통합하기로 결정했다:

  • User 컨텍스트 → Reservation 컨텍스트로 통합
  • Mileage 컨텍스트 → Payment 컨텍스트로 통합
  • Plane Ticketing + Flight → Ticketing 컨텍스트로 통합

Partnership 관계에 대한 오해

우리가 가장 크게 오해했던 부분은 Partnership 관계의 정의였다.

처음에 우리는 이렇게 생각했다:

"결제가 없으면 항공권이 발급되면 안 되잖아? 그러니까 결제와 항공권은 긴밀한 관계니까 Partnership이다."

하지만 이것은 잘못된 이해였다. Partnership은 단순히 두 컨텍스트가 비즈니스적으로 긴밀하다는 의미가 아니었다.

올바른 이해: 결제가 완료되면 이벤트를 발행하고, 그 이벤트를 받아서 항공권 발급 프로세스가 진행되는 이벤트 체이닝 방식이다. 이는 Customer/Supplier 관계로 표현되어야 한다.

Partnership은 두 컨텍스트가 서로 강하게 의존하면서 동시에 변경되어야 하는 경우에 사용되는 관계 패턴이라는 것을 배웠다.

 

Customer / Supplier

처음에는 이부분도 정보를 제공하는 주체를 Up, 정보를 제공받는 주체를 Down으로 설정을 했었다.

하지만 이 또한 올바른 방향이 아니라고 하셨다.

그래서 뭔가 우리팀이 또 깨달은 방향은

해줘 : DownStream

해줄게 : UpStream

로 결론이 났다.

 

그 후 설계 결과는 아래에 있다.

Context Map 2차 설계

QnA 세션 이후 수정한 Context Map은 3개의 주요 컨텍스트로 재구성되었다:

  1. Ticketing 컨텍스트
    • 항공편 정보 조회
    • 좌석 배정 관련 역할(유료, 자동)
    • 항공권 생성 및 고객에게 전달
  2. Reservation 컨텍스트
    • 결제 정보 전달
    • 승객정보 입력
    • 가격 계산 정책 설정(운임 클래스, 수수료 등에 의함)
  3. Payment 컨텍스트
    • 전달받은 금액에 대한 결제, 실패, 취소
    • 마일리지 적립, 차감, 정책 설정

각 컨텍스트는 Customer/Supplier 관계로 연결되어 있으며, 이벤트 기반으로 느슨하게 결합되도록 설계했다.

Aggregate Root 도출 작업

Context Map 재설계가 어느 정도 마무리되자, 각 컨텍스트 내부의 Aggregate Root를 식별하는 작업을 시작했다.

 

다이어그램을 그리면서 다음과 같은 질문들이 생겼다:

  • 각 Aggregate 간의 참조는 어떻게 이루어져야 할까?
  • ID 참조만 할 것인가, 아니면 객체 참조를 허용할 것인가?
  • Aggregate 경계를 넘는 트랜잭션은 어떻게 처리할 것인가?

이 부분은 내일 팀원들과 함께 더 깊이 논의할 예정이다.

💡 오늘 깨달은 점

  1. 컨텍스트는 조직 구조를 반영한다: DDD의 Bounded Context는 단순한 기술적 분리가 아니라, 조직의 팀 구조와 책임 경계를 반영해야 한다는 것을 배웠다.
  2. 관계 패턴의 정확한 이해가 중요하다: Partnership, Customer/Supplier, Conformist 등의 관계 패턴은 각각 명확한 의미가 있으며, 단순히 "긴밀하다/느슨하다"로 판단할 수 없다.
  3. 해줘, 해줄게

🤔 느낀 점

어제는 조금 많이 혼란스웠다. 

한번에 이해했다고 하면 그것은 거짓말이기에.. 

그래서 QnA를 통해 이해를 해보려고 했다 그래서 마지막 QnA 시간만 기다려왔다.

하지만 마지막 QnA를 안해주셨다

그래서 따로 찾아가서 질문을 진행했다.

솔직히 말하면 답변도 나는 이해하지 못했다. 다른 팀원들은 이해했을지 몰라도 

그래서 그나마 이해할 수 있었던것은 Context Map을 설계 할때 약간 재무팀, 인사팀, 개발팀 이렇게 나눠지듯이 각 도메인 별로 책임을 가지는  것으로 크게 나누었다.

솔직히 말하면 이것이 올바른 방향인지는 아직도 잘모르겠다. 왜냐하면 이것은 처음 해보는 DDD고 개발은 정답이 없기에

오늘도 고생했고 내일도 화이팅이다.!