Published on

도메인 주도 개발 시작하기 Chap9

Authors
  • avatar
    Name
    ywj9811
    Twitter

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

도메인 모델과 경계

처음 도메인 모델을 만들 때 빠지기 쉬운 함정은 도메인을 완벽하게 표현하는 단일 모델을 만드는 시도를 한다는 것이다.

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

하위 도메인마다 사용하는 용어가 다르기 때문에 올바른 도메인 모델을 개발하려면 하위 도메인마다 모델을 만들어야 한다.

모델은 특정한 컨텍스트 하에서 완전한 의미를 갖고, 이렇게 구분되는 경계를 갖는 컨텍스트를 DDD에서는 바운디드 컨텍스트라고 한다.

바운디드 컨텍스트

바운디드 컨텍스트는 용어를 기준으로 하는데, 예를 들어 카탈로그 컨텍스트와 재고 컨텍스트는 서로 다른 용어를 사용하므로 이 용어를 기준으로 컨텍스트를 분리할 수 있다.

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

이상적으로 하위 도메인과 1대1 관계라면 좋겠지만 그렇지는 않다.

즉, 카탈로그와 재고 관리가 아직 명확하게 구분되지 않은 경우 두 하위 도메인을 하나의 바운디드 컨텍스트에서 구현하기도 한다.

Untitled

또한 작은 기업은 전체 시스템을 하나의 팀에서 구현할 때도 있는데, 예를 들어 소규모 쇼핑몰은 한 개의 웹 어플리케이션으로 온라인 쇼핑을 서비스하며 하나의 시스템에서 회원, 카탈로그, 재고, 구매, 결제와 관련된 모든 기능을 제공한다.

즉, 여러 하위 도메인을 한 개의 바운디드 컨텍스트에서 구현한 것이다.

이러한 상황에서 주의할 점은 하위 도메인의 모델이 섞이지 않도록 하는 것으로, 잘못 하면 도메인 모델이 개별 하위 도메인을 제대로 반영하지 못해 하위 도메인별로 기능을 확장하기 어려워지며 결국 서비스의 경쟁력을 떨어뜨릴 수 있다.

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

Untitled

바운디드 컨텍스트는 도메인 모델을 구분하는 경계가 되기 때문에 각자 구현하는 하위 도메인에 맞는 모델을 포함한다.

따라서 비슷하지만 다른 모델을 갖는다.

Untitled

바운디드 컨텍스트 구현

도메인 모델의 데이터 구조가 바뀌면 DB 테이블 스키마도 함께 변경해야 하므로 테이블도 바운디드 컨텍스트에 포함된다.

Untitled

각 바운디드 컨텍스트는 서로 다른 구현 기술을 사용할 수도 있는데, 예를 들어 어디서는 Mysql을 사용하고 어디서는 몽고DB를 사용할 수 있다.

바운디드 컨텍스트 간 통합

Untitled

이런식으로 구성이 된다면 사용자가 제품 상세 페이지를 볼 때, 보고 있는 상품과 유사한 상품 목록을 하단에 보여주는 기능은 두가지 바운디드 컨텍스트간 통합이 필요할 것이다.

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

즉, 카탈로그의 모델을 기반으로 하는 도메인 서비스를 이용해서 상품 추천 기능을 표현해야 한다.

Untitled

이 REST API는 추천 시스템의 모델을 기반으로 하고 있기 때문에 API 응답은 카탈로그 도메인 모델과 일치하지 않을 것이다.

따라서 중간에 처리를 위한 별도 클래스를 만들어 변환을 처리하던가, 내부적으로 처리를 하여 카탈로그 도메인의 Product 모델로 변환하는 작업을 해야 한다.

Untitled

혹은, REST API와 같은 직접 통합 대신 메시지 큐를 통한 간접 통합 방식도 가능하다.

추천 시스템은 사용자가 조회한 상품 이력이나 구매 이력과 같은 사용자 활용 이력을 필요로 하는데, 이 내역을 전달할 때 메시지 시스템을 사용하는 것이 가능하다.

또한 이때는 카탈로그 도메인을 따르는 데이터를 가지게 될 것이다.

어떤 도메인 관점에서 모델을 사용하느냐에 따라 두 바운디드 컨텍스트의 구현 코드가 달라지게 도리 것이며 이를 주의해서 사용해야 한다.

바운디드 컨텍스트 간 관계

상류 컴포넌트, 하류 컴포넌트

두 바운디드 컨텍스트 간 관계 중 가장 흔한 관계는 한쪽에서 API를 제공하고 한 쪽에서는 그 API를 호출하는 관계이다.

이 관계에서 API를 사용하는 바운디드 컨텍스트는 API를 제공하는 바운디드 컨텍스트에 의존하게 된다.

Untitled

이때 API를 정의하고 공급하는 컨텍스트를 상류 컴포넌트, 사용하는 컨텍스트를 하류 컴포넌트라고 하는데, 하류 컴포넌트는 상류 컴포넌트에 의존하게 되며 만약 상류 컴포넌트가 제공하는 REST API 인터페이스가 변경되면 하류 컴포넌트의 코드도 바뀌게 된다.

공개 호스트 서비스

혹은, 하류 컴포넌트가 다수가 되면 상류 컴포넌트는 여러 하류 컴포넌트의 요구사항을 수용할 수 있는 API를 만들고 이를 서비스 형태로 공개해서 서비스의 일관성을 유지하도록 할 수 있는데, 이를 공개 호스트 서비스라고 한다.

Untitled

안티코렙션 계층

하류 컴포넌트는 상류 서비스의 모델이 자신의 도메인 모델에 영향을 주지 않도록 보호해야 하는데, 이를 위해 완충 지대를 만들어서 사용할 수 있다.

이러한 완충지대를 안티코렙션 계층이라고 하며 이러한 계층에서 두 바운디드 컨텍스트간 모델 변환을 처리할 수 있다.

이를 통해 다른 바운디드 컨텍스트의 모델에 영향을 받지 않고 도메인 모델을 유지할 수 있다.

공유 커널

두 바운디드 컨텍스트가 같은 모델을 공유하는 경우가 있는데, 예를 들어 운영자를 위한 주문 관리 도구를 개발하는 팀과 고객을 위한 주문 서비스를 개발하는 팀이 다른 경우가 있을 수 있다.

이때 주문을 표현하는 모델을 공유함으로써 주문과 관련된 중복 설계를 막을 수 있을 것이다.

이렇게 두 팀이 공유하는 모델을 공유 커널이라고 한다.

하지만, 이를 위해서는 두 팀이 밀접한 관계를 유지해야 하며 이것이 힘들다면 다음 방식으로 진행해도 괜찮다.

독립 방식

독립 방식 관게는 간단한데, 그냥 서로 통합하지 않는 방식이다.

두 바운디드 컨텍스트간에 통합하지 않으므로 서로 독립적으로 모델을 발전시키는 것이다.

컨텍스트 맵

개별 바운디드 컨텍스트에 매몰되면 전체를 보지 못할 때가 있는데, 이때 전체 비즈니스를 조망할 수 있는 지도가 컨텍스트 맵이다.

Untitled

참고로 OHS는 오픈 호스트 서비스이고, ACL은 안티코럽션 계층이다.

여기에 추가로 하위 도메인이나 조직 구조를 함께 표시할수도 있으며 정해진 방식 없이 다양한 방식이 가능하다.

간단한 도형과 선을 이용해서 각 컨텍스트의 관계를 이해할 수 있는 수준에서 그리면 된다.