기술 서적 정리/DDD Start

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

wampy 2022. 9. 5. 23:36

1. 도메인 모델과 경계

  • 한 도메인은 다시 여러 하위 도메인으로 구분되기 때문에 한 개의 모델로 여러 하위 도메인을 모두 표현하려고 시도하면 오히려 모든 하위 도메인에 맞지 않는 모델을 만들게 됨

e.g

시스템을 사용하는 사람 -> 회원

주문 도메인 -> 주문자

배송 도메인 -> 보내는 사람

  • 이렇게 하위 도메인마다 같은 용어라도 의미가 다르고 같은 대상이라도 지칭하는 용어가 다름....
  • 하위 도메인마다 사용하는 용어가 다르기 떄문에 올바른 도메인 모델을 개발하려면 하위 도메인마다 모델을 만들어야 함
  • 모델은 특정한 컨텍스트(문맥) 하에서 완전한 의미를 갖는다. 같은 제품이라도 카탈로그 컨텍스트와 재고 컨텍스트에서 의미가 서로 다르다. 이렇게 구분되는 경계를 갖는 컨텍스트를 DDD에서는 바운디드 컨텍스트라고 부른다

2. 바운디드 컨텍스트

  • 한 개의 바운디드 컨텍스트는 논리적으로 한 개의 모델을 가짐
  • 바운디드 컨텍스트는 용어를 기준으로 구분함
  • 여러 하위 도메인을 하나의 바운디드 컨텍스트에서 개발할 때 주의할 점은 하위 도메인의 모델이 섞이지 앟ㄴ도록 하는 것이다.
  • 한 프로젝트에 각 하위 도메인의 모델이 위치하면 아무래도 전체 하위 도메인을 위한 단일 모델을 만들고 싶은 유혹에 빠지기 쉽다.

3. 바운디드 컨텍스트 구현

  • 바운디드 컨텍스트는 도메인 기능을 사용자에게 제공하는 데 필요한 표현 영역, 응용 서비스, 인프라 스트럭처 영역을 모두 포함한다.

 

e.g 카탈로그 하위 도메인데 개인화 추천 기능 도입

  • 기존 카탈로그 바운디드 컨텍스트 + 추천 시스템 바운디드 컨텍스트
  • 카탈로그와 추천 바운디드 컨텍스트 간 통합이 필요한기능
  • 사용자가 제품 상세 페이지를 볼 때, 보고 있는 상품과 유사한 상품 목록을 하단에 보여줌
    • 사용자가 카탈로그 바운디드 컨텍스트에 추천 제품 목록을 요청
    • 카탈로그 바운디드 컨텍스트는 추천 바운디드 컨텍스트로부터 추천 정보를 읽어와 추천 제품 목록을 제공함
    • 카탈로그/추천 도메인 모델은 서로 다름
      • 추천 : 상품의 상세 정보 포함 X, 추천 순위와 같은 데이터...
    • 카탈로그 시스템에서는 카탈로그 도메인 모델을 이용해서 추천 상품을 표시해줘야함!!
    public class RecSystemCLient implements ProductRecommendationService {
        private ProductRepository productRepository;
    
        @Override
        public List<Product> getRecommendationsOf(ProductId id) {
            List<RecommendationItem> items = getRecItems(id.getValue());
            return toProducts(items);
        }
    
        private List<RecommendationItem> getRecntItems(String itemId) {
            // externalRecClient는 외부 추천 시스템을 위한 클라이언트라 가정
            return externalRecClient.getRecs(itemId);
        }
    
        private List<Product> toProducts(List<RecommendationItem> items) {
            return items.stream()
                .map(item -> toProductId(item.getItemId()))
                .map(prodId -> productRepository.findById(prodId))
                .collect(toList());
        }
    
        private ProductId toProductId(String itemId) {
            return new ProductId(itemId);
        }
    }
  • REST API 호출 : 두 바운디드 컨텍스트를 직접 통합
  • 메시지 큐 : 두 바운디드 컨텍스트를 간접 통합
    • 카탈로그 바운디드 컨텍스트 -> [이력을 메시지 형식으로 큐에 추가] -> 메시지 시스템
    • 추천 바운디드 컨텍스트 -> [큐에서 메시지를 가져옴] -> 메시지 시스템
    • 메시지 큐는 비동기로 메시지를 처리하기 떄문에, 카탈로그 바운디드 컨텍스트는 메시지를 큐에 추가한 뒤 추천 바운디드 컨텍스트가 메시지를 처리할 떄까지 기다리지 않고 바로 이어서 자신의 처리를 계속 함
    • 사용할 메시지의 데이터의 구조를 맞춰야 함