바운디드 컨텍스트 패턴
- 유비쿼터스 언어의 일관성을 유지
- 모델링도 가능하게 함. (경계를 명시하지 않고는 모델을 구축할 수 없음.)
- 경계가 언어의 책임을 구분 짓는다.
- "하나의 바운디드 컨텍스트 내의 언어는 특정 문제를 해결하는 비즈니스 도메인을 모델링한다."
- "다른 바운디드 컨텍스트가 동일한 비즈니스 엔티티를 대표할 수 있지만, 이는 다른 문제를 해결하는 비즈니스 도메인을 모델링한다."
- 다른 바운디드 컨텍스트의 모델은 서로 독립적으로 발전하고 구현될 수 있지만, 다른 바운디드 컨텍스트 자체는 독립적이지 않다.
=> 독립적으로 발전할 수 있지, 독립적이다 하고는 차이가 있다는 것을 기억.
=> 서로 다른 바운디드 컨텍스트와 상호작용이 필요하다. - 바운디드 컨텍스트 사이에서의 접점은 컨트랙트(Contract)라고 부른다.
컨트랙트(Contract)
- 컨트랙트의 필요성은 바운디드 컨텍스트의 모델과 언어의 차이에서 비롯.
- 각 컨트랙트는 하나 이상의 당사자에 영향을 끼치므로 서로 조율해서 정의되어야 한다.
- 확인해볼 것.
- 바운디드 컨텍스트가 다르면 사용하는 유비쿼터스 언어가 다른데, 어떤언어를 사용해야할까?
- 연동을 정의하는 DDD 패턴은 무엇이 있는가?
=> 바운디드 컨텍스트에서 작업하는 팀 간의 협력적 특정에 의해 주도됨.
=> 협력 / 사용자-제공자 / 분리형 노선 세그룹으로 나누어서 살펴볼 것.
연동을 정의하는 도메인 주도 설계 패턴
협력형 패턴 그룹
- 협력형 그룹의 패턴은 소통이 잘 되는 팀에서 구현된 바운디드 컨텍스트와 관련
- ex) 단일 팀에 의해 구현된 바운디드 컨텍스트. (한 팀의 성공이 다른 팀의 성공에 달린..)
1. 파트너십 패턴
- 파트너십 모델에서 바운디드 컨텍스트 간의 연동은 Ad-hoc 방식(직접적인 연결)으로 조정.
- 한 팀은 다른 팀에게 API 변경을 알리고 다른 팀은 충돌 없이 이를 받아들인다.
- 연동 조정은 양방향에서 진행.
- 성공적인 연동을 위해 잘 구축된 협업 실무, 높은 수준의 헌신, 팀 간의 잦은 동기화가 필수.
(기술적 관점에서 연동 피드백의 최소화를 위해 변경사항에 대한 지속적인 통합이 필수) - 이 패턴을 적용하기 위한 팀 사이에서는 협력을 위해 물리적인 거리도 가까워야 한다.
2. 공유 커널 패턴
- 바운디드 컨텍스트가 모델의 경계임에도 불구하고, 여전히 하위 도메인의 동일 모델 혹은 그 일부가 여러 다른 바운디드 컨텍스트에서 구현되는 경우 있음.
- 공유 커널(shared kernel)과 같은 공유 모델은 모든 바운디드 컨텍스트의 필요에 따라 설계가 된다.
- 공유 모델은 이를 사용하는 모든 바운디드 컨텍스트에 걸쳐서 일관성을 유지해야함.
공유 범위
- 겹치는 형태의 모델은 해당되는 바운디드 컨텍스트의 수명주기도 서로 엮이게 한다.
(공유 모델의 변경은 다른 모든 바운디드 컨텍스트에 즉시 영향을 끼침.) - 따라서 구현돼야 하는 모델의 일부분만 노출해야 공유 모델의 변경 영향을 최소화 할 수 있다.
- 공유 커널은 바운디드 컨텍스트 간에 제공될 의도가 있는 연동 관련 컨트랙트와 자료구조만으로 구성하는 것이 이상적.
구현
- 공유 커널은 소스코드의 모든 변경이 이를 사용하는 모든 바운디드 컨텍스트에 즉시 반영되도록 구현된다.
- 공유 커널은 여러 바운디드 컨텍스트에 속하므로 지속적인 통합이 필요하다.
- 따라서 공유 커널의 변경사항과 관련된 모든 바운디드 컨텍스트로 전파할 필요가 있고, 그렇지 않으면 모델의 일관성이 망가지게 된다.
공유 커널을 사용해야 하는 경우
- 공유 커널 패턴의 적용 여부를 결정하는 가장 중요한 기준은 중복 비용과 조율 비용의 비율이다.
- 해당 패턴은 바운디드 컨텍스트에 강한 의존관계를 만들기 때문에 중복 비용이 조율 비용보다 클 경우에만 적용.
(공유하는 코드베이스에 대한 변경을 조율하려는 노력보다, 공유 모델에 대한 변경을 통합할 때 드는 노력이 더 클 경우에 적용.) - 통합 비용과 중복 비용의 차이는 모델의 변동성에 달림.
(변경이 잦을수록 통합 비용은 높아진다.) - 공유 커널 사용은 신중하게 고려해야하는 실용적인 예외 케이스이다. 따라서 명분이 필요하다!
- 지리적인 제약이나 조직의 정치적 문제로 커뮤니케이션 또는 협업이 어려워 파트너십 패턴 구현이 어려울 경우 적용.
- 레거시 시스템을 점진적으로 현대화할 경우, 일시적으로 적용.
- 레거시 시스템을 서서히 바운디드 컨텍스트로 분해해서 공유 코드베이스로 만드는 것.
- 결국 공유 커널은 동일 팀에서 소유하고 구현한 바운디드 컨텍스트를 연동하는 경우 잘 맞음.
사용자-제공자 패턴 그룹
- 사용자는 제공자에게 서비스를 제공.
- 서비스 제공자는 Upstream 이고 고객 또는 사용자는 Downstream이다.
- 협력 그룹과 다르게 양 팀(업스트림과 다운스트림)은 서로 독립적으로 성공할 수 있음.
- 그러나 각 팀이 연동 컨트랙트를 주도하는 권력의 불균형이 존재하는데 이에 따라 세가지 패턴으로 나뉨
(순응주의자, 충돌 방지 계층, 오픈 호스트 서비스 패턴)
1. 순응주의자 패턴
- 힘의 균형이 서비스를 제공하는 업스트림에 있는 경우.
- 사용자의 요구를 지원할 동기가 없는 경우.
- 사용자의 선택지는 이를 받아들이거나 떠나거나!
- 즉 다운스트림 팀이 업스트림 팀의 모델을 받아들이는 바운디드 컨텍스트의 관계.
2. 충돌 방지 계층 패턴
- 다운스트림 바운디드 컨텍스트가 업스트림에 순응하지 않을 경우, 충돌 방지 계층을 두어 자신의 필요에 맞게 모델을 가공함.
- 충돌 방지 계층(ACL: anticorruption layer) 패턴은 아래 사례와 같이 제공자의 모델을 따르는 것을 원치 않거나 순응에 필요한 노력에 대한 가치가 없을 경우를 다룬다.
- 다운스트림 바운디드 컨텍스트가 핵심 하위 도메인을 포함할 경우.
- 핵심 하위 도메인은 각별한 주의가 필요하다! 제공자의 모델이 자칫 문제 도메인에 대한 모델링을 방해할 수 있다. - 업스트림 모델이 사용자의 요건에 비효율적이거나 불편한 경우.
- 바운디드 컨텍스트가 혼란에 순응하면 그 자체로 위험에 빠지게 된다. (레거시 시스템과 연동할 때 종종발생.) - 제공자가 컨트랙트를 자주 변경하는 경우.
- 사용자는 잦은 변경으로부터 모델을 보호하길 원함. 충돌 방지 계층이 있으면 제공 모델의 변경은 변환 장치에만 영향을 미침.
- 다운스트림 바운디드 컨텍스트가 핵심 하위 도메인을 포함할 경우.
3. 오픈 호스트 서비스 패턴
- 이 패턴은 힘이 사용자 측에 있을 경우를 처리.
- 제공자는 사용자를 보호하고 가능한 최고의 서비스를 제공하는데 관심이 있음.
- 구현 모델의 변경으로부터 사용자를 보호하기 위해 업스트림 제공자는 퍼블릭 인터페이스와 구현 모델을 분리.
(외부에 제공되는 퍼블릭 모델과 그 내부 구현을 다른 속도로 발전 시킬 수 있음.) - 제공자의 퍼블릭 인터페이스는 자신의 유비쿼터스 언어를 따르는 대신, 연동 지향 언어(Integration-oriented language)를 통해 사용자에게 더 편리한 프로토콜을 노출하려 함. (이러한 프로토콜을 공표된 언어 - Published Language 라고함)
- 오픈 호스트 서비스(OHS) 패턴은 충돌 방지 계층 패턴과 반대로 제공자가 사용자 대신 내부 모델 번역을 구현.
- 바운디드 컨텍스트의 구현 모델과 연동 모델을 분리하면 업스트림 바운디드 컨텍스트는 다운스트림 컨텍스트에 영향을 주지 않으면서 자신의 구현을 자유롭게 발전가능. (이미 사용하는 공표된 언어에 대한 영향이 없을 경우에 한해)
- 또한 연동 모델을 분리하면 업스트림 바운디드 컨텍스트는 이미 공표된 언어의 여러 버전을 동시에 노출할 수 있어서 사용자가 점진적으로 새로운 버전으로 이관할 수 있게 한다.
분리형 노선
- 전혀 협력하지 않을 경우의 옵션.
1. 커뮤니케이션 이슈
- 조직의 규모와 내부 정치 요인으로 인한 커뮤니케이션의 어려움으로 인한 협업 회피.
- 이러한 경우, 여러 바운디드 컨텍스트 내에서 기능을 중복해서 가져가고 각자의 길을 가는 것이 더 비용효과적.
2. 일반 하위 도메인
- 중복된 하위 도메인의 특성으로 인할 경우.
- 만일 일반 하위 도메인이 일반 솔루션과 연동하는 것이 쉽다면, 각 바운디드 컨텍스트 내에서 각자 연동하는 것이 더욱 비용 효과적.
- 예로 로깅 프레임워크가 있음.(한 곳에서 이를 통합된 서비스로 노출하면 복잡성이 매우 커지므로 바람직하지 않을 것.)
3. 모델의 차이
- 바운디드 컨텍스트의 모델 간의 차이.
- 모델이 너무 달라 순응주의자 관계가 불가능하고, 충돌 방지 계층을 구현하는 것도 기능 중복보다 비용이 더 클 수 있다.
핵심 하위 도메인을 연동할 경우에는 협업 없는 분리형 노선은 피해야 한다.
하위 도메인의 중복 구현은 회사의 전략을 효과적이고 효율적으로 구현하는 것을 어렵게 한다.
컨텍스트 맵
- 컨텍스트 맵은 시스템의 바운디드 컨텍스트와의 연동을 시각적으로 표현.
시각적 표기법이 제공하는 중요한 전략적 통찰
거시적 설계 관점
- 컨텍스트 맵은 시스템의 구성요소와 구현하는 모델의 개요를 제공
커뮤니케이션 패턴
- 컨텍스트 맵은 시스템의 구성요소 간의 커뮤니케이션 패턴을 묘사한다.
- 어떤 팀이 협력하고, 충돌 방지 계층과 분리형 노선 패턴과 같은 '덜 친밀한' 연동 패턴을 선호하는지 보여준다.
조직적 문제
- 컨텍스트 맵은 조직적 문제에 대한 통찰력을 제공한다.
- 가령 업스트림 팀의 다운스트림 사용자가 모두 충돌 방지 계층을 구현하는 데 의존하거나, 분리형 노선 패턴의 모든 구현이 한팀에 집중된다면???? 무엇을 의미할까?
유지보수
- 컨택스트 맵은 프로젝트 초기부터 도입해서 새로운 바운디드 컨텍스트와 기존요소에 대한 수정을 반영하는 것이 이상적.
- 컨텍스트 맵은 여러 팀이 작업한 정보를 담기 때문에 다 함께 유지보수하는 것이 제일 좋다.
한계
- 여러 하위 도메인에 걸친 시스템의 바운디드 컨텍스트에는 작동하는 여러 연동 패턴이 있을 수 있음.
(여러 연동 패턴은 표현이 복잡하다) - 바운디드 컨텍스트가 단일 하위 도메인에 국한되더라도, 하위 도메인의 모듈이 다른 통합 전략을 필요로 하는 경우 여전히 여러 통합 패턴이 있을 수 있음.
'Design > DDD' 카테고리의 다른 글
[DDD 첫걸음] 2-2. 전술적 설계 - 복잡한 비즈니스 로직 다루기. (0) | 2023.06.11 |
---|---|
[DDD 첫걸음] 2-1. 전술적 설계 - 간단한 비즈니스 로직 구현. (0) | 2023.04.25 |
[DDD 첫걸음] 1-3. 전략적 설계 - 도메인 복잡성 관리. (0) | 2023.04.12 |
[DDD 첫걸음] 1-2. 전략적 설계 - 도메인 지식 찾아내기. (0) | 2023.04.05 |
[DDD 첫걸음] 1-1. 전략적 설계 - 비즈니스 도메인 분석하기. (0) | 2023.04.04 |