개발/DDD

전략적 설계 - Context Mapping

배워서, 남주자 2025. 2. 7. 00:04

 

도메인 주도 설계(DDD) 의 전략적 설계(혹은 전략적 패턴) 에서 쓰이는 컨텍스트 매핑이 무엇이며, 컨텍스트 매핑에서 자주 사용하는 패턴에 대해 공부하고 실무에 어떻게 적용할지 설명합니다.


컨텍스트 매핑이란?

도메인 주도 설계(DDD)에서 여러 개의 바운디드 컨텍스트(Bounded Context)서로 어떤 관계를 맺고 있는지 시각적으로 표현하는 기법입니다.


* 바운디드 컨텍스트(Bounded Context)는 특정 도메인 모델이 일관되게 유지되는 경계를 의미합니다. 특히, 하나의 시스템 내에서도 여러 개의 바운디드 컨텍스트가 존재할 수 있습니다.
예를 들어, 제가 담당하는 셀러 오피스 시스템에서는 상품, 주문, 회원, 클레임 등등 여러개의 컨텍스트가 존재합니다. 

게다가 서로 다른 시스템 간의 바운디드 컨텍스트가 동일한 도메일을 다루더라도, 각 바운디드 컨텍스트 내에서의 모델은 다를 수 있습니다. 예를 들어, 셀러 오피스 시스템의 상품 바운디드 컨텍스트의 모델상품 관리 시스템의 상품 바운디드 컨텍스트의 모델다를 수 있습니다. (아니, 각자의 두 시스템이 발전해 갈수록 반드시 다를겁니다.)


컨텍스트 매핑을 왜 해야 하나요?

필자의 경험에 의하면, 거대한 시스템 내의 도메인 경계를 여러개의 바운디드 컨텍스트로 나눈 후 각각의 바운디드 컨텍스트 대로 팀으로 쪼개지곤 했었습니다. (*물론 여러개의 바운디드 컨텍스트를 하나의 팀에서 담당하는 경우도 많습니다.)

바운디드 컨텍스트는 각자 도생할 수 없고 협력이 필요하는 경우가 많습니다. 

시스템에 새로운 기능이 추가되고 커갈수록 컨텍스트 간의 협업도 많아지겠죠.

만약 우리가 컨텍스트 간의 관계를 명확히 하지 않으면 아래와 같은 부작용이 나타납니다.

  • 바운디드 컨텍스트 내에서 도메인 모델이 일관되지 않아지고
  • 협업하는 팀 간의 책임이 불분명해지고
  • 서비스 간 의존성이 얽혀 유지보수가 어려워 짐

이를 방지하고 해소하기 위해 컨텍스트 매핑을 통해 각 바운디드 컨텍스트 간 책임과 관계 및 연결방식을 시각적으로 문서화하고 이를 기반으로 시스템을 설계해야 합니다.

사실 우리는 이미 바운디드 컨텍스트(*팀) 간 회의와 회의록(*컨텍스트 매핑)을 작성하며 이미 어느정도 추상적으로 컨텍스트 매핑 과정을 하고 있습니다.
 다만, 명확한 컨텍스트 매핑 패턴을 정의하고 사용하면 추상적이 아니라 구체적으로 표현하기에, 사람간(또는 팀간) 의 커뮤니케이션 비용을 줄여주고 명확하게 일을 할 수 있기 때문에 거창한 것처럼 보이는 컨텍스트 매핑, blah blah 패턴 등의 용어를 사용하는 것이라 생각합니다.
 마치 우리가 코드 리뷰를 할 때, "이 코드는 여기를 이렇게 이렇게 리팩토링 해서 OCP 를 지켜주게 하면 좋을것 같아요." 라고 길게 리뷰하기 보다는 "이 코드는 GoF의 다자인 패턴 중 상태패턴을 적용해서 OCP 를 지킬 수 있게 하면 좋을 것 같아요." 라고 명확하게 이야기하여 커뮤니케이션 비용을 줄이는 것과 비슷하다고 생각해주시면 될 것 같습니다.

컨텍스트 매핑 패턴

 

오픈 호스트 서비스 패턴

 

  • 하나의 서비스가 공통 인터페이스(API, 메시지 등)를 통해 여러 소비자가 접근할 수 있도록 제공하는 방식
  • 예: 재고 조회, 재고 등록 등 공개 API를 제공하는 재고 시스템, 그리고 재고를 각자의 서비스에서 직접 제어하지 않으며 재고 서비스를 통해서 제어하는 상품 등록 시스템, 주문 시스템

 

순응자 패턴

 

  • 소비자가 공급자의 모델을 그대로 따르는 경우
  • 자체적인 모델을 설계할 자유도가 적음

 

변질 방지층 패턴

 

  • 외부 시스템과의 직접적인 모델 의존을 방지하기 위해 중간 계층을 둠
  • 코드레벨에서는 주로 facade 패턴을 통해 구현함
  • 외부 시스템의 스펙에는 외부 시스템의 스펙으로 대응하지만, 외부 시스템의 스펙에 대응하는 내부 도메인 모델은 변질 되지 않도록 해야 함
  • 내부 도메인 모델을 보호하기 위해서 Adapter나 Translator 가 이 역할을 수행
  • 예: 외부 결제 시스템 ↔ 내부 정산 시스템 (외부 결제 데이터를 내부 모델로 변환)

 

 

공유 커널 패턴

 

  • 일부 공통 모델을 공유하지만, 완전한 결합은 하지 않는 관계
  • 공유된 모델이 변경될 경우, 협업을 통해 조정해야 함
  • 예: 정산 도메인 ↔ 주문 도메인 (정산을 위한 주문 정보 일부 공유)

 

파트너십 패턴

 

 

  • 두 컨텍스트가 대등한 관계이며, 협력을 통해 목표를 달성해야 하는 경우
  • 만약 한쪽이 변경되면 다른 쪽도 변경이 필요할 가능성이 크다는 점에서 공유 커널 패턴과 차이점이 있
  • 예: 상품 관리 시스템 ↔ 주문 관리 시스템 (상품 정보를 정확하게 유지해야 주문도 올바르게 처리됨)

 

고객 - 공급자 패턴

 

 

  • 한쪽이 다른 한쪽의 서비스를 소비하는 관계
  • 이 패턴이 일반적으로 가장많이 사용되는 패턴임
  • 고객은 공급자에게 요구사항을 표현하고 공급자는 고객의 요구를 계획을 세워 어느 정도 반영하지만, 독립적으로 운영됨
  • 예: 문의 시스템(공급자) ↔ 셀러 오피스 시스템(고객) (셀러 오피스가 어떤 형태의 문의 시스템의 정보를 필요로 한다고 요청하지만, 문의 시스템이 셀러 오피스 시스템에 의존하지는 않음)

 

분할 방식 패턴

 

  • 두 바운디드 컨텍스트 간 의존된 관계가 없다면 분할 방식 패턴으로 적용
  • 나중에 다시 합치기가 어려우므로 통합이 나중에라도 필요할 지 면밀히 검토 후 분할 방식 패턴을 적용해야 함

 


실무에 어떻게 적용할까요?

 

시스템 내 바운디드 컨텍스트 정의

  • 먼저, 도메인 분석을 통해 바운디드 컨텍스트를 나누어 정의
  • 예: 셀러 오피스, 주문 시스템, 정산 시스템, 배송 시스템 등

컨텍스트 간 관계를 패턴으로 매핑

  • 바운디드 컨텍스트 간의 의존성을 위에서 설명한 패턴으로 매핑
  • 예:
    • 주문 시스템 → 배송 시스템: Customer-Supplier
    • 정산 시스템 ↔ 주문 시스템: Shared Kernel
    • 외부 결제 시스템 ↔ 내부 정산 시스템: Anticorruption Layer

컨텍스트 매핑 다이어그램 작성

  • 컨텍스트 간의 관계를 시각적으로 표현하여 팀원들과 공유하면 더 효과적