DDD 도메인 주도 설계 9장
in Development on DDD
DDD - 도메인 주도 설계
앞으로 적어갈 글은 최범균님의 저서 DDD START!를 읽고 요약 - 정리한 글입니다.
제 9장 : 도메인 모델과 BOUNDED CONTEXT
제 9장 도메인 모델과 BOUNDED CONTEXT
도메인 모델과 경계
처음 도메인 모델을 만들 때 빠지기 쉬운 함정은 도메인을 완벽하게 표현하는 단일 모델을 만드는 시도를 하는 것이다.
한 도메인은 다시 여러 도메인으로 구분된다.
- 하나의 모델로 여러 하위 도메인을 표현하려고 하면 모든 하위 도메인에 맞지 않는 모델을 만들게 된다.
상품이라는 모델이 있다고 가정하자.
- 카탈로그에서의 상품
- 재고 관리에서의 상품
- 주문에서의 상품
- 배송에서의 상품
위의 상품들은 이름만 같지 실제 의미하는 것이 다르다.
반대로 시스템을 사용하는 사람을 회원 도메인에서는 회원이라 부르지만 주문 도메인에서는 주문자라고 부르며, 배송 도메인에서는 보내는 사람이라고 부른다.
논리적으로 같은 존재처럼 보이지만 하위 도메인에 따라 다른 용어를 사용하는 경우도 있다.
하위 도메인 마다 같은 용어라도 의미가 다르며, 같은 대상이라도 지칭하는 용어가 다를 수 있으므로 하나의 모델로 모든 하위 도메인을 표현하는 시도는 올바른 방법도 아니며 불가능하다.
모델은 특정한 컨텍스트하에서 비로소 완전한 의미를 갖는다.
같은 제품이라도 카탈로그 컨텍스트와 재고 컨텍스트에서 의미가 서로 다르다.
이렇게 구분되는 경계를 갖는 컨텍스트를 DDD에서는 BOUNDED CONTEXT라고 부른다.
BOUNDED CONTEXT
BOUNDED CONTEXT는 모델의 경계를 결정하며 한 개의 BOUNDED CONTEXT는 논리적으로 한 개의 모델을 갖는다.
BOUNDED CONTEXT는 용어를 기준으로 구분한다.
이상적으로는 하위 도메인과 BOUNDED CONTEXT가 1:1 관계를 갖으면 좋겠지만 현실은 그렇지가 않다.
BOUNDED CONTEXT는 기업의 팀 구조에 따라 결정되기도 한다.
큰 기업에서는 하나의 도메인 안에 두 하위 도메인을 두 BOUNDED CONTEXT로 나눠서 개발한다.
작은 기업에서는 두 하위 도메인을 하나의 BOUNDED CONTEXT에서 구현하기도 한다.
만약 온라인 쇼핑이라는 BOUNDED CONTEXT에서 여러 개의 하위 도메인들을 BOUNDED CONTEXT로 나눌 때는 패키지를 활용해서 BOUNDED CONTEXT를 만들도록 한다.
이처럼 BOUNDED CONTEXT를 나누지 않으면 하위 도메인 모델이 서로 뒤섞여서 결과적으로는 도메인별 기능 확장이 어려워지게 된다.
BOUNDED CONTEXT의 구현
BOUNDED CONTEXT가 항상 도메인 모델만 포함하는 것은 아니다.
도메인 기능을 사용자에게 제공하기 위한 표현, 응용 서비스, 도메인, 인프라스트럭처 모두를 포함한다.
- 모든 BOUNDED CONTEXT를 도메인 주도로 개발할 필요는 없다.
- 가령 상품의 리뷰처럼 간단한 도메인 로직이라면 CRUD 방식으로 구현해도 상관이 없다.
BOUNDED CONTEXT 간 통합
카탈로그 하위 도메인에 개인화 추천 기능을 도입하기로 결정했다고 가정해보자.
기존 카탈로그 시스템을 개발하던 팀과 별도로 추천 시스템을 담당하는 팀이 새로 생겨서 이 팀에서 주도적으로 추천 시스템을 만든다면?
카탈로그 하위 도메인에는 기존 카탈로그를 위한 BOUNDED CONTEXT와 추천 기능을 위한 BOUNDED CONTEXT가 생기게 된다.
두 팀이 관련된 BOUNDED CONTEXT를 개발하면 자연스럽게 통합이 발생한다.
카탈로그 시스템은 추천 시스템으로부터 추천 데이터를 받아오기는 하지만, 카탈로그 시스템에서는 추천의 도메인 모델이 아닌 카탈로그 도메인 모델을 사용해서 추천 상품을 표현해야한다.
- 그러면 카탈로그 시스템에서는 추천 시스템으로 API 요청을 보내 데이터를 받아오게 될 텐데, 이 데이터는 카탈로그 도메인에 맞지 않을 것이므로 변환 작업이 필요하다.
만약 두 모델 간의 변환 작업이 복잡하다면 변환 처리를 위한 별도 클래스를 만들고 이 클래스에서 변환을 처리해도 된다.
HTTP는 두 BOUNDED CONTEXT를 직접 통합하는 방법이다.
- 직접 통합 대신 간접 통합을 하려면 어떻게 해야할까? 그런 경우라면 메시지 큐를 사용할 수 있다.
마이크로 서비스와 BOUNDED CONTEXT
여기까지 보면 BOUNDED CONTEXT를 나누는 것은 어찌보면 MSA와도 유사해보인다.
MSA의 특징은 BOUNDED CONTEXT와 매우 잘 어울린다.
BOUNDED CONTEXT는 독립적으로 배포하고 모니털이하고 확장하게 되는데 이는 MSA의 특징이기도 하다.
BOUNDED CONTEXT 간 관계
BOUNDED CONTEXT는 어떤 식으로 연결된다.
두 BOUNDED CONTEXT 간 관계 중 가장 흔한 관계는 한쪽에서 API를 제공하고 다른 한쪽에서 그 API를 호출하는 관계다.
이때 API를 사용하는 BOUNDED CONTEXT는 API를 제공하는 BOUNDED CONTEXT에 의존하게 된다.
여기서 카탈로그는 downstream 컴포넌트이며 추천은 upstream 컴포넌트가 된다.
상류 컴포넌트가 하류 컴포넌트에서 사용할 수 있는 통신 프로토콜을 정의하고 이를 공개한다. 이를 공개 호스트 서비스라고 부른다.
가장 대표적인 예가 바로 검색이다.
이러한 서비스들은 API를 통해 통신하는데 만약 RestTemplate과 같은 HTTP 클라이언트를 사용했다면 이 RestTemplate이 외부 시스템이 내 도메인 모델을 침범하지 않도록 막아주는 Anticorruption Layer가 된다.
공유 커널이라고 해서 두 팀이 하나의 모델을 공유함으로써 중복 개발을 막을 수 있는 모델이 존재한다.
장점은 중복을 줄여주는 것이오 단점은 두 팀이 밀접하게 협업하지 않으면 모델이 깨지므로 개발이 지연되는 문제가 발생할 수 있다는 점이다.
마지막으로는 SEPARATE WAY, 독립 방식 관계가 존재한다.
위는 극단적인 SEPARATE WAY의 예시이다.
수동으로 하는 방식이 나쁜것은 아니지만 규모가 커질수록 수동 통합에는 한계가 존재하기 마련이다.
- 그래서 일반적으로는 두 독립적인 BOUNDED CONTEXT를 통합하기 위해 중간 다리를 놓기도 한다.
컨텍스트 맵
개별 BOUNDED CONTEXT에 매몰되어서 전체를 못보게 되는 경우가 종종 있다.
나무가 아닌 숲을 보기 위해 전체 비즈니스를 조망할 수 있는 지도가 바로 컨텍스트 맵이다.
컨텍스트 맵을 그리는 규칙은 없다. 화이트보드, PPT, Whatever it is!
컨텍스트 맵은 시스템의 전체 구조를 보여준다.
BOUNDED CONTEXT를 조절하고 사업의 핵심 도메인을 위해 조직 역량을 어떤 BOUNDED CONTEXT에 집중할지 파악하는데 도움이 된다.
Reference
DDD START! - 최범균님 -