9.1 도메인 모델과 경계
하위 도메인마다 같은 용어라도 의미가 다르고, 같은 대상이라도 지칭하는 용어가 다를 수 있기 때문에 한 개의 모델로 모든 하위 도메인을 표현하려는 시도는 올바른 방법이 아니며 표현할 수도 없음!
- 하위 도메인마다 모델 만들어야 함
- 각 모델은 명시적으로 구분되는 경계를 가져서 섞이지 않도록 해야 함
- 모델은 특정한 컨텍스트(문맥) 하에서 완전한 의미를 가짐
- 구분되는 경계를 갖는 컨텍스트를 바운디드 컨텍스트(Bounded Context)라고 함
9.2 바운디드 컨텍스트
- 바운디드 컨텍스트
- 모델의 경계를 결정
- 논리적으로 한 개의 모델 가짐
- 용어를 기준으로 구분
- 실제로 사용자에게 기능을 제공하는 물리적 시스템으로 도메인 모델은 이 바운디드 컨텍스트 안에서 도메인을 구현
이상적으로 하위 도메인과 바운디드 컨텍스트가 일대일 관계를 가지면 좋겠지만 현실은 그렇지 않을 때가 많음!
- 바운디드 컨텍스트는 기업의 팀 조직 구조에 따라 결정되기도 함
- 여러 하위 도메인을 하나의 바운디드 컨텍스트에서 개발할 때 주의할 점
- 하위 도메인의 모델이 섞이지 않도록 해야 함
- 전체 하위 도메인을 위한 단일 모델을 만들지 않도록 조심
- 하위 도메인마다 구분되는 패키지를 갖도록 구현해야 함 -> 하위 도메인을 위한 모델이 서로 뒤섞이지 않고 하위 도메인마다 바운디드 컨텍스트를 갖는 효과!
9.3 바운디드 컨텍스트 구현
바운디드 컨텍스트는 도메인 기능을 사용자에게 제공하는 데 필요한 표현 영역, 응용 서비스, 인프라스트럭처 영역과 테이블까지 모두 포함
- 모든 바운디드 컨텍스트를 도메인 주도로 개발할 필요는 없음
- 기능을 유지보수하는 데 큰 문제가 없다면 서비스-DAO로 구성된 CRUD 방식도 가능
- 한 바운디드 컨텍스트에서 두 방식을 혼합해서 사용 가능
- ex) CQRS - 상태 변경과 관련된 기능은 도메인 모델 기반으로 구현, 조회 기능은 서비스-DAO 이용해서 구현 가능
- 각 바운디드 컨텍스트는 서로 다른 구현 기술 사용 가능
- ex) 웹 MVC는 스프링 MVC 사용, 리포지터리 구현 기술로는 JPA/하이버네이트 사용하는 바운디드 컨텍스트 존재 가능
- 바운디드 컨텍스트가 반드시 사용자에게 보여지는 UI를 가지고 있어야 하는 것은 아님
- ex) UI를 처리하는 서버를 두고 UI 서버에서 바운디드 컨텍스트와 통신해서 사용자 요청을 처리하는 방법도 있음
9.4 바운디드 컨텍스트 간 통합
- 두 바운디드 컨텍스트 간 통합이 발생하는 경우가 있음
- REST API를 호출해서 두 바운디드 컨텍스트 직접 통합하기
- 인프라스트럭처 영역에 위치한 도메인 서비스를 구현하는 클래스는 외부 시스템과의 연동을 처리하고 외부 시스템의 모델과 현재 도메인 모델 간의 변환 책임짐
- 두 모델 간의 변환 ㅗ가정이 복잡하면 변환 처리를 위한 별도 클래스를 만들어서 변환을 처리해도 됨
- 메시지 큐를 사용해서 간접적으로 두 바운디드 컨텍스트 통합하기
- 메시지 큐는 비동기로 메시지를 처리하기 때문에 메시지를 큐에 추가하고 다른 바운디드 컨텍스트가 메시지를 처리할 때까지 기다리지 않고 바로 이어서 자신의 처리를 계속할 수 있음
- 두 바운디드 컨텍스트가 사용할 메시지의 데이터 구조를 맞춰야 함 -> 주고 받을 데이터 형식에 대한 협의 필요
- 어떤 도메인 관점에서 모델을 사용하느냐에 따라 두 바운디드 컨텍스트의 구현 코드가 달라지게 됨
- 큐를 누가 제공하느냐에 따라서도 데이터 구조 결정됨
마이크로서비스와 바운디드 컨텍스트
- 마이크로서비스는 애플리케이션을 작은 서비스로 나누어 개발하는 아키텍처 스타일
- 개별 서비스를 독립된 프로세스로 실행하고 각 서비스가 REST API나 메시징을 이용해서 통신하는 구조 가짐
- 각 바운디드 컨텍스트는 모델의 경계를 형성하는데 바운디드 컨텍스트를 마이크로서비스로 구현하면 자연스럽게 컨텍스트별로 모델이 분리됨
9.5 바운디드 컨텍스트 간 관계
- REST API
- API를 사용하는 바운디드 컨텍스트는 API를 제공하는 바운디드 컨텍스트에 의존하게 됨
- 하류 컴포넌트는 상류 컴포넌트가 제공하는 데이터와 기능에 의존
- 상류 컴포넌트는 일종의 서비스 공급자 역할을 하며 하류 컴포넌트는 그 서비스를 사용하는 고객 역할
- 상류 컴포넌트와 하류 컴포넌트를 개발하는 각 팀은 상호 협력이 필수
- 상류팀과 하류팀은 개발 계획을 서로 공유하고 일정을 협의해야 함
- 상류 컴포넌트는 하류 컴포넌트가 사용할 수 있는 통신 포로토콜 정의하고 공개
- 상튜팀의 고객인 하류팀이 다수 존재하면 상류팀은 여러 하류팀의 요구사항을 수용할 수 있는 API 만들고 서비스 형태로 공개해서 서비스의 일관성 유지 -> 공개 호스트 서비스
- 공개 호스트 서비스(OPEN HOST SERVICE)
- 상류팀은 각 하류 컴포넌트의 요구사항을 수용하는 단일 API를 만들어 이를 공개
- 각 하류팀은 공개된 API 사용해서 각자 필요한 기능 구현
- 안티코럽션 계층
- 상류 컴포넌트의 서비스는 상류 바운디드 컨텍스트의 도메인 모델 따르기 때문에 하류 컴포넌트는 상류 서비스의 모델이 자신의 도메인 모델에 영향을 주지 않도록 보호해 주는 완충 지대
- 두 바운디드 컨텍스트 간의 모델 변환을 처리하기 때문에 다른 바운디드 컨텍스트의 모델에 영향을 받지 않고 내 도메인 모델을 유지할 수 있음
- 공유 커널(SHARED KERNEL)
- 두 바운디드 컨텍스트가 같은 모델을 공유하는 경우, 두 팀이 공유하는 모델을 공유 커널이라고 함
- 장점: 중복을 줄여줌 -> 다만 같은 모델을 공유하는 두 팀이 밀접한 관계 유지해야 함, 그렇지 않으면 공유 커널의 장점보다 더 큰 문제 발생 가능
- 독립 방식(SEPARATE WAY)
- 서로 통합하지 않는 방식
- 두 바운디드 컨텍스트 간의 통합 수동으로 이루어짐
- 수동 통합의 한계로 인해 규모 커지면 두 바운디드 컨텍스트 통합해 주는 별도의 시스템 만들어야 할 수도 있음
9.6 컨텍스트 맵
- 컨텍스트 맵
- 바운디드 컨텍스트 간의 관계를 표시하여 전체 비즈니스를 조망할 수 있도록 하는 지도
- 한국에 각 바운디드 컨텍스트의 경계가 명확하게 드러나고 서로 어떤 관계를 맺고 있는지 알 수 있음
- 시스템의 전체 구조를 보여줌
- 하위 도메인과 일치하지 않는 바운디드 컨텍스트를 찾아 도메인에 맞게 바운디드 컨텍스트를 조절하고 사업의 핵심 도메인을 위해 조직 역량을 어떤 바운디드 컨텍스트에 집중할지 파악하는데 도움을 줌