DDD - 도메인 복잡성 관리: 바운디드 컨텍스트
이 포스트에서는 아래 내용에 대해 알아본다.
- 바운디드 컨텍스트
- 비즈니스 도메인의 복잡성을 해결
- 시스템의 고수준 아키텍처 구성 요소
- 바운디드 컨텍스트 설계
이 포스트에서는 바운디드 컨텍스트가 왜 유비쿼터스 언어를 만들기 위해 필수적인 요소인지에 대해 알아본다.
이후 발견한 지식을 비즈니스 도메인 모델로 변환하는 방법과 바운디드 컨텍스트를 활용하여 소프트웨어 시스템의 구성 요소를 설계해본다.
목차
1. 일관성 없는 모델
프로젝트의 성공을 보장하려면 모든 이해관계자가 의사 소통에 사용할 수 있는 유비쿼터스 언어를 개발하는 것이 중요하다.
언어는 비즈니스 도메인의 내부 동작과 기본 원칙에 대한 도메인 전문가의 멘탈 모델을 반영해야 한다.
목표는 유비쿼터스 언어를 사용하여 소프트웨어 설계의 의사 결정을 내리는 것이기 때문에 언어는 명확하고 일관성있어야 한다.
모호성, 암묵적인 가정, 관련없는 세부 사항이 없어야 한다.
하지만 조직 규모에 따라 도메인 전문가의 멘탈 모델은 일관성이 없을 수 있다.
같은 비즈니스 도메인에서도 도메인 전문가마다 서로 다른 모델을 사용할 수 있는데 그 예시에 대해 알아보자.
한 회사의 마케팅 부서와 영업 부서가 리드(lead) 라는 단어를 다르게 사용한다고 해보자.
- 마케팅 부서
- lead 는 누군가가 제품 중 하나에 관심이 있다는 알림을 나타냄
- 잠재 고객의 연락처 정보를 수신하는 이벤트는 lead 로 간주됨
- 영업 부서
- lead 는 영업 프로세스의 전체 수명주기를 나타냄
- lead 는 단순한 이벤트가 아니라 장기적으로 진행되는 과정
이 경우 영업과 마케팅 부서의 도메인 전문가 사이의 ‘lead’ 의 멘탈 모델에 차이가 있다.
이러한 다양한 비즈니스 모델을 소프트웨어로 표현할 때 아래와 같은 문제가 발생한다.
영업 부서의 복잡한 모델을 마케팅 부서에 적용한다면 광고 캠페인을 최적화하는 것보다 훨씬 더 많은 불필요한 세부 사항이 있기 때문에 엔지니어링이 과도한 솔루션을 얻게 된다.
마케팅 관점에 따라 영업 모델을 단순화하려고 하기엔 영업 프로세스를 관리하고 최적화하기에 마케팅은 너무 단순하므로 엔지니어링이 조금 더 필요한 솔루션을 얻게 된다.
이러한 딜레마를 2가지 방식으로 해결하려고 한다고 해보자.
- 전통적인 솔루션인 모든 종류의 문제에 사용할 수 있는 단일 모델 설계
- 단일 모델은 모든 것에 적합해야 하지만 결국에는 아무 소용이 없음
- 무엇을 하든지 항상 복잡성에 직면하게 됨
- 즉, 관련없는 세부 사항을 필터링해야 하는 복잡성, 필요한 것을 찾는 복잡성 등에 직면하게 됨
- 문맥상 정의에 문제가 있는 용어 앞에 접두사 추가
- ‘마케팅 리드’, ‘영업 리드’ 와 같이 접두사 추가
- 이럴 경우 2가지 문제가 발생함
- 인지 부하 유발
- 각 모델을 언제 사용해야 할지 충돌하는 모델을 구현할 수록 실수할 확률이 높아짐
- 모델의 구현이 유비쿼터스 언어와 일치하지 않음
- 아무도 대화에서 접두사를 사용하지 않을 것임
- 인지 부하 유발
이제 이러한 시나리오를 다루기 위한 DDD 패턴 중 하나인 바운디드 컨텍스트에 대해 알아보자.
2. 바운디드 컨텍스트
DDD 의 솔루션은 유비쿼터스 언어를 여러 개의 작은 언어로 나뉜 후 각 언어를 적용할 수 있는 명시적인 바운디드 컨텍스트에 할당하는 것이다.
위에서 마케팅과 영업이라는 2 가지 바운디드 컨텍스트를 식별할 수 있다.
‘lead’ 라눈 용어는 2 가지 바운디드 컨텍스트에 모두 존재한다.
각 바운디드 컨텍스트에서 단일 의미를 갖는 한, 세분화된 유비쿼터스 언어 각각은 일관성을 띄며 도메인 전문가의 멘탈 모델을 따를 수 있다.
2.1. 모델 경계
모델은 실제 세계의 복사본이 아닌 복잡한 시스템을 이해하는데 도움을 주기 위해 구조화한 것이다.
모델에 경계가 없다면 현실 세계의 복제본처럼 확장될 것이다.
따라서 모델의 경계(= 바운디드 컨텍스트)를 정의하는 것은 모델링 프로세스의 본질이다.
예를 들어 항공, 해상, 지하철 등 각 지도는 특정 목적 범위 내에서만 유용하고 일관성이 있다.
지하철 노선도가 해상에서 의미가 없듯이 하나의 바운디드 컨텍스트의 유비쿼터스 언어는 다른 바운디드 컨텍스트의 범위에는 완전히 관련이 없다.
바운디드 컨텍스트는 유비쿼터스 언어의 일관성이 유지되는 경계로, 유비쿼터스 언어의 용어, 규칙은 해당 바운디드 컨텍스트 안에서만 일관성이 있다.
2.2. 정제된 유비쿼터스 언어
유비쿼터스 언어는 조직 전체에서 ‘유비쿼터스’하게 사용해야 한다는 의미에서의 유비쿼터스가 아니다.
유비쿼터스 언어는 바운디드 컨텍스트 경계 안에서만 보편적으로 적용되며, 바운디드 컨텍스트에 포함된 모델을 설명하는데만 집중한다.
2.3. 바운디드 컨텍스트 범위
서로 다른 도메인 전문가들은 동일한 비즈니스 엔티티에 대해 상충되는 멘탈 모델을 갖고 있다.
비즈니스 도메인을 모델링하기 위해 모델을 분할하고, 각 세분화된 모델에 적용 가능한 컨텍스트(= 바운디드 컨텍스트) 를 엄격하게 정의해야 한다.
유비쿼터스 언어의 일관성은 해당 언어의 가장 넓은 경계를 식별하는데 도움이 될 뿐이다.
일관성 없는 모델과 용어가 있기 때문에 바운디드 컨텍스트를 더 이상 커질 수 없다.
유비쿼터스 언어의 범위(= 바운디드 컨텍스트)를 정의하는 것은 전략적인 설계 의사 결정이다.
바운디드 컨텍스트의 크기에 정답은 없다.
유비쿼터스 언어의 경계가 넓을수록 일관성을 유지하기 어렵다.
큰 유비쿼터스 언어를 더 작고 관리하기 쉬운 도메인으로 나누는 것은 도움이 될 수 있지만, 바운디드 컨텍스트를 작게 만드는 것은 설계를 통합하는 오버헤드가 생기므로 역효과를 낼 수 있다.
따라서 바운디드 컨텍스트의 크기에 대한 결정은 문제 도메인이 무엇이냐에 따라 달라진다.
큰 바운디드 컨텍스트에서 세분화된 바운디드 컨텍스트를 추출하는 이유는 보통 2가지 이유가 있다.
- 새로운 소프트웨어 엔지니어링 팀을 구성하거나 시스템의 일부 비기능 요구 사항을 해결하기 위해 추출
- 예) 단일 바운디드 컨텍스트에 있던 일부 컴포넌트의 개발 수명주기를 분리
- 바운디드 컨텍스트의 나머지 기능과 독립적으로 확장하기 위해 추출
응집된 기능을 여러 바운디드 컨텍스트로 분할하게 되면 비즈니스 요구사항이 변경될 때 여러 바운디드 컨텍스트에 동시에 영향을 미치고, 변경에 대한 동시 배포가 이루어지게 되므로 각 컨텍스트가 독립적으로 발전하는 능력을 저해한다.
이런 비효율적인 분해를 피하기 위해 하위 도메인 을 찾아야 한다.
같은 데이터에서 작동하는 응집된 유스케이스의 집합을 식별하여 그것이 여러 개의 바운디드 컨텍스트로 분해되지 않도록 해야 한다.
바운디드 컨텍스트의 경계를 지속해서 최적화하는 법에 대해서는 추후 다룰 예정입니다.
3. 바운디드 컨텍스트 vs 하위 도메인
비즈니스 도메인은 여러 하위 도메인으로 구성된다.
위에서 비즈니스 도메인을 세분화된 문제 도메인 또는 바운디드 컨텍스트의 집합으로 분해하는 개념에 대해 알아보았는데 이렇게 비즈니스 도메인을 분해하는 2 가지 방법은 중복처럼 보이지만 사실 그렇지 않다.
하위 도메인과 바운디드 컨텍스트, 두 경계가 필요한 이유에 대해 알아보자.
3.1. 하위 도메인
기업의 비즈니스 전략을 이해하려면 비즈니스 도메인을 분석해야 하는데 분석 단계에는 다양한 하위 도메인(핵심, 지원, 일반) 을 식별하는 작업이 포함된다.
요구사항 정의는 소프트웨어 엔지니어가 아닌 비즈니스가 담당하고, 소프트웨어 엔지니어는 하위 도메인을 식별하기 위해 비즈니스 도메인을 분석한다.
3.2. 바운디드 컨텍스트
바운디드 컨텍스트는 소프트웨어 엔지니어에 의해 설계된다.
3.3. 하위 도메인과 바운디드 컨텍스트 간의 상호작용
비현실적이지만 이론적으로 단일 모델이 전체 비즈니스 도메인에 적용될 수 있다.
이러한 전략을 소규모 시스템에서 효과적일 수 있다.
위 그림에서 모델이 충돌하면 아래 그림처럼 도메인 전문가의 멘탈 모델을 따라 시스템을 바운디드 컨텍스트로 분해할 수 있다.
모델이 여전히 크고 유지보수하기 어려운 경우 더 작은 바운디드 컨텍스트로 분해할 수 있다.
아래 그림처럼 각 하위 도메인에 대한 바운디드 컨텍스트로 나눌 수 있다.
중요한 것은 하위 도메인은 발견하는 것이고, 바운디드 컨텍스트는 설계한다는 점이다.
하위 도메인은 비즈니스 전략에 의해 정의된다.
소프트웨어 엔지니어는 특정 프로젝트의 컨텍스트와 제약 조건을 해결하기 위해 소프트웨어 솔루션과 바운디드 컨텍스트를 설계할 수 있다.
4. 경계
바운디드 컨텍스트 패턴은 물리적 경계와 소유권 경계를 규정하기 위한 DDD 도구이다.
4.1. 물리적 경계
바운디드 컨텍스트는 모델 경계 뿐 아니라 이를 구현하는 시스템의 물리적 경계 역할도 한다.
각 바운디드 컨텍스트는 개별 서비스/프로젝트로 구현되어야 한다.
즉, 구현/진화/버전 관리를 각각의 다른 바운디드 컨텍스트와 독립적으로 해야 한다.
바운디드 컨텍스트 간의 명확한 물리적 경계를 통해 각 바운디드 컨텍스트를 요구사항에 가장 적합한 기술 스택으로 구현할 수 있다.
바운디드 컨텍스트는 여러 하위 도메인을 포함할 수 있다.
이럴 경우 바운디드 컨텍스트는 물리적 경계이고, 하위 도메인은 논리적 경계이다.
논리적 경계는 네임 스페이스나 모듈, 패키지 같은 다른 이름을 갖는다.
4.2. 소유권 경계
바운디드 컨텍스트는 한 팀에서만 구현/유지 관리해야 한다.
서로 다른 바운디드 컨텍스트로 분리된 모델과 시스템을 명시적으로 연동하기 위해서는 사전에 정의된 통신 프로토콜을 이용하여 연동한다.
정리하며..
- 도메인 전문가의 멘탈 모델에 내재된 충돌을 발견할 때마다 유비쿼터스 언어를 여러 개 바운디드 컨텍스트로 분해해야 함
- 유비쿼터스 언어는 바운디드 컨텍스트 범위 내에서 일관성이 있어야 함
- 서로 다른 바운디드 컨텍스트에서는 동일한 용어라도 다른 의미를 가질 수 있음
- 바운디드 컨테그트와 유비쿼터스 언어는 한 팀에서 만들고 유지보수해야 함
- 바운디드 컨텍스트는 시스템을 서비스, 하위 시스템 등의 물리적 구성 요소로 분해함
- 각 바운디드 컨텍스트의 수명 주기를 서로 독립적임
참고 사이트 & 함께 보면 좋은 사이트
본 포스트는 블라드 코노노프 저자의 도메인 주도 설계 첫걸음을 기반으로 스터디하며 정리한 내용들입니다.