DDD - 바운디드 컨텍스트 연동
이 포스트에서는 아래 내용에 대해 알아본다.
- 바운디드 컨텍스트 간 소통과 통합을 구성하는 다양한 패턴
- 이러한 패턴은 바운디드 컨텍스트에서 작업하는 팀 간의 협력적 특성에 의해 주도됨
- 컨텍스트 맵
이 포스트에서는 연쇄적인 변경으로부터 스스로를 보호하는데 사용할 수 있는 바운디드 컨텍스트를 연동하기 위한 다양한 패턴에 대해 알아본다.
시스템 구성 요소를 연동하는 방법에 영향을 주는 기술적/조직적 제약 사항에 대해 알아보고, 다양한 상황과 제한을 다루는 연동 패턴에 대해 알아본다.
그리고 각 패턴이 소프트웨어 개발팀 간의 협업에 어떻게 영향을 미치는지에 대해 알아본다.
컨텍스트 맵은 도해적 방법으로 시스템의 바운디드 컨텍스트 사이에서 커뮤니케이션하는 방법을 구상하고, 프로젝트의 통합과 협업 환경의 조감도를 제공하는 역할을 한다.
바운디드 컨텍스트 패턴은 유비쿼터스 언어의 일관성을 유지하고, 모델링을 가능하게 해준다.
각 바운디드 컨텍스트의 모델은 서로 독립적으로 발전하고 구현될 수 있지만, 바운디드 컨텍스트 자체는 독립적이지 않다.
시스템의 구성 요소가 서로 상호 작용하듯이 바운디드 컨텍스트들도 서로 독립적으로 발전하되, 상호 작용해야 한다.
결국, 바운디드 컨텍스트 사이에는 항상 접점이 있는데 이를 컨트랙트(contract) 라고 한다.
각 컨트랙트는 하나 이상의 당사자에게 영향을 끼치므로 서로 조율해서 컨트랙트를 정의해야 한다.
바운디드 컨텍스트가 다르면 사용하는 유비쿼터스 언어도 다르다.
그렇다면 연동이 필요할 경우 컨트랙트는 어떤 언어를 사용해야 할 지에 대한 고민이 필요한데, 이렇게 연동에 대한 고민은 솔루션 설계에서 다루어져야 한다.
목차
1. 협력형(cooperation) 패턴 그룹
소통이 잘 되는 팀에서 구현된 바운디드 컨텍스트와 관련이 있다.
예) 단일 팀에 의해 구현된 바운디드 컨텍스트
1.1. 파트너십 패턴
파트너십 모델에서 바운디드 컨텍스트 간의 연동은 ad-hoc 방식으로 조정한다.
ad-hoc
일반적으로 특정한 계획에 따라 미리 정의된 것이 아니라 특정 목적을 위해 그 순간에 필요한 대응 방안
한 팀이 다른 팀에게 API 의 변경을 알리면 다른 팀은 충돌 없이 이를 받아들인다.
연동의 조정은 양방향에서 한다.
성공적인 연동을 위해서는 잘 구축된 협업 실무, 높은 수준의 헌신, 팀 간의 잦은 동기화가 필수이다.
파트너십 패턴은 동기화와 커뮤니케이션의 어려움 때문에 지리적으로 떨어져 있는 팀에게는 적합하지 않을 수 있다.
1.2. 공유 커널(shared kernel) 패턴
바운디드 컨텍스트가 모델의 경계임에도 불구하고, 하위 도메인의 동일 모델 혹은 그 일부가 여러 다른 바운디드 컨텍스트에서 구현되는 경우가 있다.
공유 커널과 같은 공유 모델은 모든 바운디드 컨텍스트의 필요에 따라 설계되므로 이를 사용하는 모든 바운디드 컨텍스트에 걸쳐서 일관성을 유지해야 한다.
예) 사용자의 권한을 관리하는 모델
- 공유 범위
- 겹치는 형태의 모델은 해당되는 바운디드 컨텍스트의 수명 주기도 서로 엮이게 함
- 따라서 변경의 연쇄 영향을 최소화하기 위해 양쪽의 겹치는 모델을 제한하여 바운디드 컨텍스트에서 공통으로 구현되어야 하는 모델의 일부분만 노출하도록 해야 함
- 구현
- 공유 커널은 소스 코드의 모든 변경이 이를 사용하는 모든 바운디드 컨텍스트에 즉시 반영되도록 구현됨
- 조직에서 단일 저장소를 사용한다면 여러 바운디드 컨텍스트는 동일한 소스 파일을 참조할 수 있음
- 이것이 불가능하다면 공유 커널을 각 바운디드 컨텍스트의 전용 프로젝트로 떼어내서 연결 라이브러리처럼 바운디드 컨텍스트에서 참조하는 방식으로 함
공유 커널 패턴의 적용 여부의 기준은 중복 비용과 조율 비용의 비율이다.
공유 커널 패턴을 적용하면 바운디드 컨텍스트 간에 강한 의존 관계를 만들기 때문에 중복 비용이 조율 비용보다 클 경우에만 적용하는 것이 좋다. (= 두 바운디드 컨텍스트가 공유하는 코드 베이스에 대한 변경을 조율하려는 비용보다 공유하는 모델에 대한 변경을 통합하는데 드는 비용이 더 클 경우에 적용)
통합 비용과 중복 비용의 차이는 모델의 변동성(volatility) 에 달려있다.
변경이 잦을수록 통합 비용이 높아진다.
겹치는 형태의 모델인 공유 커널은 사실상 여러 팀이 함께 개발하는 경우가 많으느데, 같은 팀이 공유 커널을 구현하지 않는다면 이는 단일 팀 원칙을 위반하는 것이므로 공유 커널을 사용하는데에는 명분이 필요하다.
일반적인 공유 커널의 적용 사례는 아래와 같다.
- 지리적인 제약이나 조직의 저치적인 문제로 커뮤니케이션, 협업이 어려워서 파트너십 패턴을 구현하기 어려운 경우
- 레거시 시스템을 점진적으로 현대화하는 경우
- 시스템을 서서히 바운디드 컨텍스트로 분해해서 공유 코드 베이스로 만드는 것이 실용적인 중간 솔루션이 될 수 있음
파트너십 패턴처럼 즉흥적으로 바운디드 컨텍스트를 연동하면 시간이 흐르면서 컨텍스트의 경계가 희미해질 수 있는데, 이 경우 바운디드 컨텍스트의 연동 컨트랙트를 명시적으로 정의하는데 공유 커널을 사용할 수 있다.
2. 사용자-제공자 패턴 그룹
제공자는 사용자에게 서비스를 제공한다.
대부분의 경우 사용자 혹은 제공자 둘 중의 한 팀이 연동 컨트래트를 주도하는 권력의 불균형이 존재한다.
2.1. 순응주의자 패턴
힘의 균형이 서비스를 제공하는 팀에 있는 경우이다.
사용자의 요구를 지원할 동기가 없는 경우가 그렇다.
제공자의 모델에 따라 정의된 연동 컨트랙트를 제공할 뿐이므로 사용자는 이를 받아들이거나 떠나거나 둘 중 하나이다.
이런 힘의 불균형은 조직 외부의 서비스 제공자와 연동하는 경우 혹은 단순히 조직의 정치적 이유인 경우가 있다.
2.2. 충돌 방지 계층(ACL: AntiCorruption Layer) 패턴
순응주의자 패턴에서 힘의 균형은 제공자에게 치우쳐있는데 이를 사용자가 순응하지 않는 경우 충돌 방지 계층을 통해 제공자의 바운디드 컨텍스트 모델을 스스로의 필요에 맞게 가공하여 사용하는 경우이다.
충돌 방지 계층 패턴은 아래와 같이 제공자의 모델을 따르는 것을 원치 않거나 순응에 필요한 노력이 가치가 없을 경우에 다룬다.
- 사용자의 바운디드 컨텍스트가 핵심 하위 도메인을 포함하는 경우
- 제공자의 모델이 사용자의 요건에 비효율적이거나 불편한 경우
- 제공자가 컨트랙트를 자주 변경하는 경우
모델링 관점으로 볼 때 사용자가 제공자의 모델을 변환하면 자신의 바운디드 컨텍스트와 상관없는 외부의 개념으로부터 자신을 안전히 보호할 수 있다.
충돌 방지 계층을 구현하는 방법에 대해서는 추후 다룰 예정입니다. (p. 57)
2.3. 오픈 호스트 서비스(OHS: Open-Host Service) 패턴
오픈 호스트 서비스 패턴은 힘이 사용자 측에 있는 경우를 처리한다.
제공자는 사용자를 보호하고 가능한 최고의 서비스를 제공하는데 관심이 있다.
구현 모델의 변경으로부터 사용자를 보호하기 위해 제공자는 퍼블릭 인터페이스와 구현 모델을 분리하여 외부에 제공되는 퍼블릭 모델과 그 내부 구현을 다른 속도로 발전시킬 수 있다.
제공자의 퍼블릭 인터페이스는 자신의 유비쿼터스 언어를 따르는 대신 연동 지향 언어를 통해 사용자에게 더 편리할 프로토콜을 노출하는데 이런 퍼블릭 프로토콜을 공표된 언어(published language) 라고 한다.
바운디드 컨텍스트의 구현 모델과 연동 모델을 분리하는 제공자의 컨텍스트는 사용자의 컨텍스트에 영향을 주지 않으면서 자신의 구현을 자유롭게 발전시킬 수 있는데 이는 수정된 구현 모델을 사용자가 이미 사용하는 공표된 언어로 번역할 수 있을때만 가능하다.
3. 분리형 노선(Seperated ways)
분리형 노선은 서로 전혀 협력하지 않는 경우이다.
핵심 하위 도메인을 연동할 경우에는 협업 없는 분리형 노선은 피해야 한다.
하위 도메인의 중복 구현은 회사의 전략을 효율적으로 구현하는 것을 어렵게 한다.
3.1. 커뮤니케이션 이슈
협업을 회피하는 일반적인 이유는 조직의 규모나 내부 정치 요인으로 인한 커뮤니케이션의 어려움 때문인데, 팀이 협업과 합의에 어려움을 겪는다면 여러 바운디드 컨텍스트 내에서 기능을 중복하여 가져가고 각자의 길을 가는 것이 더 비용 효과적이다.
3.2. 일반 하위 도메인
중복된 하위 도메인의 특성도 분리된 길을 가야할 수도 있다.
만일 일반 하위 도메인이 일반 솔루션과 연동하는 것이 쉽다면 각 바운디드 컨텍스트 내에서 각자 연동하는 것이 더 비용 효과적일 수 있다.
예) 로깅 프레임워크 사용 시 바운디드 컨텍스트 중 한 곳에서 이를 서비스로 노출하는 것은 바람직하지 않음
여러 컨텍스트 간에 기능 중복이 없을 경우의 장점보다 그 솔루션을 연동했을 때 더해지는 복잡성이 더 큼
이런 경우 기능 중복이 협업보다 비용이 더 저렴함
3.3. 모델의 차이
바운디드 컨텍스트 모델 간의 차이가 너무 커서 순응주의자 관계가 불가능하고, 충돌 방지 계층을 구현하는 것도 기능 중복보다 비용이 더 큰 경우 팀이 각자의 길을 가는 것이 더 비용 효과적이다.
4. 컨텍스트 맵
컨텍스트 맵은 시스템의 바운디드 컨텍스트와의 연동을 시각적으로 표현하여 다양한 수준에서 전략적 통찰력을 제공한다.
- 거시적 설계 관점
- 컨텍스트 맵은 시스템의 구성 요소와 구현하는 모델의 개요를 제공함
- 커뮤니케이션 패턴
- 컨텍스트 맵은 시스템의 구성 요소 간의 커뮤니케이션 패턴을 묘사함
- 어떤 팀이 협력하고, 충돌 방지 계층과 분리선 노선 패턴과 같은 덜 친밀한 연동 패턴을 선호하는지 보여줌
- 조직적 문제
- 컨텍스트 맵은 조직적 문제에 대한 통찰력을 제공함
- 특정 제공자 팀의 사용자가 모두 충돌 방지 계층을 구현하거나 분리형 노선 패턴의 모든 구현이 한 팀에 집중된다면 그 팀은 눈여겨 볼 필요가 있음
참고 사이트 & 함께 보면 좋은 사이트
본 포스트는 블라드 코노노프 저자의 도메인 주도 설계 첫걸음을 기반으로 스터디하며 정리한 내용들입니다.