Hyun's Wonderwall

[EFUB 4기 BE Lead] 도메인 주도 개발 시작하기 - 9. 도메인 모델과 바운디드 컨텍스트 본문

Study/Java, Spring

[EFUB 4기 BE Lead] 도메인 주도 개발 시작하기 - 9. 도메인 모델과 바운디드 컨텍스트

Hyun_! 2024. 4. 8. 20:45

EFUB 4기 BackEnd Lead_ 도메인 주도 개발 스터디

  • 스터디 커리큘럼: 최범균, "도메인 주도 개발 시작하기: DDD 핵심 개념 정리부터 구현까지"
  • 3주차 과제: Chapter 9. 도메인 모델과 바운디드 컨텍스트

Chapter 9. 도메인 모델과 바운디드 컨텍스트

  • Keywords: 바운디드 컨텍스트, 바운디드 컨텍스트 간 통합과 관계

9.1 도메인 모델과 경계

한 개의 모델로 모든 하위 도메인을 표현하려는 시도는 불가능하다.

- 하위 도메인마다 같은 용어라도 의미가 다르고, 같은 대상이라도 지칭하는 용어가 다를 수 있다.

 

올바른 도메인 모델을 개발하려면 하위 도메인마다 모델을 만들어야 한다.

- 각 모델은 명시적으로 구분되는 경계를 가져서 섞이지 않도록 해야 한다. 여러 하위 도메인의 모델이 섞이면 모델의 의미가 약해지고, 여러 도메인의 모델이 서로 얽히기 때문에 각 하위 도메인별로 다르게 발전하는 요구사항을 모델에 반영하기 어려워진다.

- 모델은 특정한 컨텍스트(문맥)하에서 완전한 의미를 갖는다. 같은 제품이라도 카탈로그 컨텍스트와 재고 컨텍스트에서 이름이 서로 다르다.

- 이렇게 구분되는 경계를 갖는 컨텍스트를 DDD에서는 바운디드 컨텍스트라고 부른다.

9.2 바운디드 컨텍스트

바운디드 컨텍스트는 모델의 경계를 결정하며 한 개의 바운디드 컨텍스트는 논리적으로 한 개의 모델을 갖느다.

- 바운디드 컨텍스트는 용어를 기준으로 구분한다.

- 카탈로그 컨텍스트와 재고 컨텍스트는 서로 다른 용어를 사용하므로 이 용어를 기준으로 컨텍스트를 분리할 수 있다.

- 또한 바운디드 컨텍스트는 실제로 사용자에게 기능을 제공하는 물리적 시스템으로, 도메인 모델은 이 바운디드 컨텍스트 안에서 도메인을 구현한다.

 

하위 도메인과 바운디드 컨텍스트는 일대일 관계가 아닐 수도 있다.

- 주문 하위 도메인 아래에 주문 바운디드 컨텍스트와 결제 금액 계산 바운디드 컨텍스트가 존재하는 경우

- 카탈로그 하위 도메인과 재고 하위 도메인이라는 두 하위 도메인을 상품 바운디드 컨텍스트에서 구현하는 경우

- 규모가 작은 경우 여러 하위 도메인을 한 개의 큰 바운디드 컨텍스트에서 구현할 수도 (이때 주의점: 하위 도메인의 모델이 섞이지 않도록 해야 한다.

- 비록 한 개의 바운디드 컨텍스트가 여러 하위 도메인을 포함하더라도, 하위 도메인마다 구분되는 패키지를 갖도록 구현해야 한다. -> 하위 도메인을 위한 모델이 서로 뒤섞이지 않고 하위 도메인마다 바운디드 컨텍스트를 갖는 효과

 

바운디드 컨텍스트는 구현하는 하위 도메인에 알맞은 모델을 포함한다.

- 카탈로그 바운디드 컨텍스트의 Product는 상품이 속할 Category와 연관을 갖지만, 재고 바운디드 컨텍스트의 Product는 그렇지 않다.

9.3 바운디드 컨텍스트 구현

바운디드 컨텍스트는 도메인 기능을 제공하는 데 필요한 모든 요소를 포함한다.

(주문 바운디드 컨텍스트가 포함: [표현 영역, 응용 서비스, 도메인, 인프라스트럭처, DBMS])

- 도메인 모델 뿐만 아니라 도메인 기능을 사용자에게 제공하는 데 필요한 표현 영역, 응용 서비스, 인프라스트럭처 영역을 모두 포함한다. 도메인 모델의 데이터 구조가 바뀌면 DB 테이블 스키마도 함께 변경해야 하므로 테이블도 바운디드 컨텍스트에 포함된다. 표현 영역은 HTML 페이지를 생성할 수도, REST API를 제공할 수도.

 

모든 바운디드 컨텍스트를 반드시 도메인 주도로 개발할 필요는 없다. ex. 상품의 리뷰는 CRUD 방식으로 구현해도 된다. 즉 DAO와 데이터 중심의 밸류 객체를 이용해서 리뷰 기능을 구현해도 기능을 유지 보수하는 데 큰 문제가 없다.

(리뷰 바운디드 컨텍스트가 포함 : [표현 영역, 서비스, DAO, DBMS])

서비스-DAO 구조를 사용하면 도메인 기능이 서비스에 흩어지게 되지만 도메인 기능 자체가 단순하면 서비스-DAO로 구성된 CRUD 방식을 사용해도 코드를 유지 보수하는 데 문제되지 않는다.

 

한 바운디드 컨텍스트에서 두 방식을 혼합해서 사용할 수도 있다. 대표적인 예: CQRS 패턴.

CQRS(Command Query Responsibility Segregation)는 상태를 변경하는 명령 기능과 내용을 조회하는 쿼리 기능을 위한 모델을 구분하는 패턴이다. 이 패턴을 단일 바운디드 컨텍스트에 적용하면 상태 변경과 관련된 기능은 도메인 모델 기반으로 구현하고 조회 기능은 서비스-dao를 이용해서 구현할 수 있다.

 

각 바운디드 컨텍스트는 서로 다른 구현 기술을 사용할 수도 있다.

- DBMS대신 NoSQL일수도

 

바운디드 컨텍스트는 UI를 갖지 않을 수도 있다. 상품의 상세 정보를 보여주는 페이지를 생각해 보자.

- 카탈로그 바운디드 컨텍스트로 상세 정보를 읽어온 뒤(HTML 응답), 리뷰 바운디드 컨텍스트의 rest api를 직접 호출해서 로딩한 JSON 데이터를 알맞게 가공해 리뷰 목록을 보여줄 수도 있다.

- UI를 처리하는 서버를 두고 UI 서버에서 바운디드 컨텍스트와 통신해 사용자 요청을 처리할 수도 있다. 이 구조에서 UI 서버는 각 바운디드 컨텍스트를 위한 파사드 역할을 수행한다. 브라우저가 UI 서버에 요청을 보내면 UI 서버는 카탈로그와 리뷰 바운디드 컨텍스트로부터 필요한 정보를 읽어와 조합한 뒤 브라우저에 응답을 제공한다.

9.4 바운디드 컨텍스트 간 통합

카탈로그 팀에서 추천 시스템을 만들기로 했다. 카탈로그 하위 도메인에는 기존 카탈로그를 위한 바운디드 컨텍스트와 추천 기능을 위한 바운디드 컨텍스트가 생긴다.

두 팀이 관련된 바운디드 컨텍스트를 개발하면 두 바운디드 컨텍스트간 통합이 필요하다. 카탈로그와 추천 바운디드 컨텍스트 간 통합이 필요한 기능은 다음과 같다.

* 사용자가 제품 상세 페이지를 볼 때, 보고 있는 상품과 유사한 상품 목록을 하단에 보여준다.

 

사용자가 카탈로그 바운디드 컨텍스트에 추천 제품 목록을 요청하면 카탈로그 바운디드 컨텍스트는 추천 바운디드 컨텍스트로부터 추천 정보를 읽어와 추천 제품 목록을 제공한다. 이때 카탈로그 컨텍스트와 추천 컨텍스트의 도메인 모델은 서로 다르다.

카탈로그는 제품을 중심으로 도메인 모델을 구현하지만 추천은 추천 연산을 위한 도메인 모델을 구현한다. (EX. 추천 연산은 상품 번호 대신 아이템 ID라는 용어를 사용해서 식별자를 표현하고 추천 순위와 같은 데이터를 담게 된다.)

카탈로그 시스템은 추천 시스템으로부터 추천 데이터를 받아오지만, 카탈로그 시스템에서는 추천의 도메인 모델을 사용하기보다는 카랄로그 도메인 모델을 사용해서 추천 상품을 표현해야 한다. 

 

- 인프라스트럭처 영역의, 도메인 서비스를 구현한 클래스 ResSystemClient 및 REST API를 호출하는 방식에 대한 설명

 

* REST API를 호출하는 것은 두 바운디드 컨텍스트를 직접 통합하는 방식이다.

* 간접 통합하는 방법도 있다. 대표적으로 메시징.

[ 카탈로그 바운디드 컨텍스트가 사용자의 이력을 메시지 형식으로 메시지 큐에 추가 -> 추천 바운디드 컨텍스트는 큐에서 메시지를 가져옴 ]

- 메시지 큐는 비동기로 메시지를 처리한다.

- 두 바운디드 컨텍스트는 사용할 메시지 데이터의 데이터 구조를 맞춰야 한다. 어떤 도메인 관점에서 모델을 사용하냐에 따라 두 바운디드 컨텍스트의 구현 코드가 달라진다. 메시징 큐를 누가 제공하냐에 따라 데이터 구조가 결정된다. "출판/구독" 모델을 따른다.

 

// 마이크로서비스와 바운디드 컨텍스트

9.5 바운디드 컨텍스트 간 관계

두 바운디드 컨텍스트는 다양한 방식으로 관계를 맺는다.

가장 흔한 관계는 한쪽에서 API를 제공, 다른 한쪽에서 그 API를 호출하는 관계. REST API가 대표적이다.

9.6 컨텍스트 맵

컨텍스트 맵은 시스템의 전체 구조를 보여준다. 이는 하위 도메인과 일치하지 않는 바운디드 컨텍스트를 찾아 도메인에 맞게 바운디드 컨텍스트를 조절하고 사업의 핵심 도메인을 위해 조직 역량을 어떤 바운디드 컨텍스트에 집중할지 파악하는 데 도움을 준다.