본문 바로가기
DDD

14장_모델의 무결성 유지(Bounded Context)

by kooangelo 2021. 10. 8.

4부 전략설계

  • 전략설계 : 모델링 과정을 매우 복잡한 도메인까지 확장하는 원리를 제시 - p354
  • 기업 시스템의 목표 : 전체 업무를 아우르는 긴밀하게 통합된 시스템
    통합의 이점을 잃어버리지 않으면서도 모듈화를 달성해서 갖가지 시스템이 다양한 업무 활동을 위해 조화롭게 상호작용하게끔 만드는것은 쉽지 않다 - p354
  • 전략설계 원칙 - p354
    - 상호운용성(Interoperability)과 상승효과(Synergy)를 잃지 않으면서 각 부분 간의 결합도는 낮추고 명확화
    - 모델에 촛점을 맞춰 시스템의 개념적 핵심, 즉 시스템의 비전을 포착해야
  • Context : 분명하게 드러나지 않지만 실제로는 가장 근본적인 설계 원칙 - p354
  • 성공적인 모델 : 규모와는 상관없이 모순되거나 정의가 겹치지 않고 처음부터 끝까지 논리적인 일관성을 지녀야 함(Mutually Exclusive Collectively Exhaustive, 상호배제와 전체포괄 : 항목들이 상호 배타적이면서 모였을 때는 완전히 전체를 이루는 것, 겹치지 않으면서 빠짐없이 나눈 것 - 을 포함하는 듯한 의미) - p354
  • 모델이 적용되는 Bounded Context(제한된 컨텍스트, BC)를 분명하게 정의하고, 다른 Context와의 관계를 정의해서 모델의 품질을 유지 - p355

 

  • Charge(요금) 객체를 서로 다른 Context(업무 영역을 의미하는 듯)에서 각 팀은 자신들만의 맥락에서만 유효한 요금 속성을 대상으로 (설계, 구현 ... 이상한 결과) ... 이러한 모순점을 해결하지 않고 코드를 결합했기에 신뢰할 수 없는 SW가 만들어짐 - p357

 

(BC의 필요성, 통합 시스템의 Risk) - p358 ~ 359

  • 대규모 시스템의 도메인 모델을 완전하게 단일화한다는 것은 타당하지 않거나 비용 대비 효과적이지 않을것이다
  • 한번에 많은 레거시를 교체하려 할지도 모름
  • 대규모 프로젝트에서는 능력에 비해 조율에 드는 비용이 너무 커서 난관에 처할지 모름
  • 특화된 요구사항이 있는 Application에서는 요건을 충족하지 못해 Application의 행위를 다른 곳에 둘 수밖에 없는 모델의 가능성
  • 단일 몰델로 모두를 만족시키려해서 모델을 사용하기 어렵게 만드는 복잡한 대안의 가능성
  • 모델의 분화는 기술적 관심사만큼이나 정치적 분열과 다양한 경영상의 우선순위로 발생하기 마련
  • 팀 구성과 개발 프로세스의 결과로 서로 다른 모델이 나타날수도
  • (통합하기 어려운 기술적 차이로 인한 모델의 분리)
  • 개별적인 모델을 기반으로 작성된 코드가 한데 섞이면 많은 버그가 발생하고 신뢰성이 떨어지며 이해하기 힘든 SW가 만들어짐, 아울러 팀 구성원 간의 의사소통이 혼란스러워짐 - p362

 

그림14-1 모델 무결성 패턴에 대한 Navigation Map - p360

 

 

Bounded Context(BC)

  • 각 모델의 적용 가능 범위 - p359
  • 개별팀이 수행하는 업무일수도 있음, 팀 조직으로 Context 경계 - p362
  • 모델이 적용되는 Context를 명시적으로 정의 - p362
  • DB 스키마와 같은 물리적인 관점에서 명시적으로 설정 - p362
  • 경계내에서는 모델을 일관된 상태로 유지하고 경계 바깥의 이슈 때문에 초점이 흐려지거나 혼란스러워져서는 안됨 - p362
  • BC는 팀 구성원이 어떤 부분에서 일관성을 지녀야 하고 다른 Context와 어떤 식으로 관련돼 있는가를 명확하게 이해할수 있게 특정 모델의 적용범위를 제한해야 - p362
  • 서로 다른 Context에 대해 용어, 개념과 규칙, UL에 포함된 다른 표현 방식에 차이를 보이는 서로 다른 모델을 적용 - p362
  • 경계에 걸쳐 이뤄지는 통합에는 필수적으로 어느 정도의 번역(Translation)이 수반, 이를 명시적으로 분석 - p363
  • 모델을 책임지는 팀에서는 영속화를 비롯한 각 객체의 전체 생명주기를 다룸
    이 팀에서 DB스키마를 통제, 스키마는 모델에 의해 결정됨 - p364
  • BC의 목적 : Context 안에서 업무를 진행하는 팀에서 얻게 되는 것은 바로 명확함
    반면에 BC 밖의 팀이 얻게 되는 것은 자유로음 - p365
  • 뚜렷이 구분되는 모델 요소를 결합할 경우의 문제 - p366
    - 중복 : 변경될 때 마다 두 군데를 갱신하고 변환해야 함
    - 허위 동족 언어(False Cognates : 용어는 같지만 실제 쓰임 등의 의미가 다른 경우)
      같은 용어(또는 객체)를 사용하는 두 사람이 같은 것을 이야기하고 있다고 생각하지만 실제로는 그렇지 않은 경우
      서로의 코드를 침범하게 되고 DB에 이상한 불일치 가능성, 의사소통 혼란
  • BC와 AG의 관계는?
    BC : AG = 1 : N?

 

 

Continuous Integration(지속적 통합, CI)

  • Context 제한되면 CI프로세를 토대로 모델의 단일화를 유지할 수 있음 - p359
  • 다수의 사람이 동일한 BC내에서 작업할 경우 모델이 나눠질수 있음
    그렇다고 더 작은 Context로 분할한다면 의미있는 통합과 응집성을 잃게될 수 있음 - p367
  • CI : 내부적으로 균열일 발생할 때 이를 빠르게 포착하고 정정할 수 있을 정도로 Context내의 모든 작업을 빈번하게 병합해서 일관성을 유지하는 것 - p367
  • 모델의 통합과 구현의 통합 - p368
  • 구현 산출물은 모델의 균열을 조기에 드러내는 체계적인 병합/빌드/테스트 프로세스를 토대로 통합 - p368 ~ 369
    - 단계적이고 재생 가능한 병합/빌드 기법
    - 자동화된 테스트 스위트
    - 수정사항이 통합되지 않은 상태로 존재할 수 있는 시간을 적당히 짧게 유지하는 규칙
    (MSA에서 말하는 Rapid/Frequent/Reliable Deploy 의 개념이 포함된 듯)
    - 애자일 프로젝트에서는 적어도 매일 한 번씩은 각 개발자가 변경한 코드를 병합
    - (동일 Context내에서 모델/코드의 단편화, 균열, 불일치 등)이 발생했다는 사실을 빠르게 알려줄 수 있는
      자동화된 테스트와 함께 모든 코드와 그 밖의 산출물을 빈번하게 병합하는 프로세스 수립필요
    - CI는 오직 하나의 BC내에서만 필수적이다

 

 

Context Map(CM)

  • 프로젝트의 Context와 각 Context간의 관계, 전체 관계 조망 - p359
  • Context와 Context 사이의 연결이라는 큰 그림을 제시하면서 각 Context가 차지하는 영역을 보여줌 - p365
  • BC간에 코드를 재사용하는 것은 위험하므로 피해야 함
    기능과 데이터는 번역과정(Adapter, Wrapping, Mapping 등을 의미)을 거쳐 통합해야 함
    서로 다른 Context간의 관계를 정의하고 프로젝트상의 모든 모델 Context를 아우르는 전체적인 뷰를 만들어 혼란 방지 필요 (MSA에서 서비스간의 API/PUB/SUB을 통한 Interaction 과 유사한 의미인 듯)- p370
  • CM : 프로젝트 관리와 SW 설계 영역 사이에 걸쳐 있는 개념
    대개 Context의 경계는 팀 조직의 윤곽에 따라 정해짐 - p370
  • 의사소통(서비스간 Communication, Interaction) 을 위해 Context 간의 번역에 대한 윤곽을 명확하게 표현하고 Context간에 공유해야하는 정보를 강조함으로써 모델과 모델이 만나는 경계 지점 서술(정의) 필요 - p371
  • CM을 특정한 형식으로 문서화할 필요는 없지만 지도와 같은 형태로 표현할 필요는 있음 - p371
  • 일단 응집도 높은 CM이 마련되면 변경 요건이 있을수 있고, 심사숙고한 후 팀 조직 또는 설계 변경 가능 - p372
  • CM 예 - p374, 그림 14-3
  • 번역 예 - p377, 그림 14-7 (MSA에서는 API/PUB/SUB 등으로 이러한 Translation, Provider/Consumer Interaction 역할 필요)
  • 다른 BC와 접촉하는 지점은 테스트할 때 특히 중요(Translator 등) - p378
    BC A모델이 바뀌고 있습니다. 그러니 우리의 BC B의 Context 번역기를 변경할 예정 - p379

 

Shared Kernel(SK)

  • p381의 SK 그림 필요
  • 두 팀간에 공유하기로 한 모데인 모델의 부분집합을 명시
    모델의 부분집합뿐 아니라 모델 요소와 연관된 코드나 DB설계까지도 포함
    명시적으로 공유하는 부분들은 다른팀과 협의없이는 변경할 수 없음 - p382
  • SK도 자주 통합해라, 하지만 개별팀에서 수행하는 CI보다는 더 적은 빈도로 통합하라
    통합할때는 양팀에서 작성한 테스트를 모두 실행하라
    양팀에서 작성한 모든 테스트를 통과해야 하므로 자동화된 테스트 스위트는 통합되어야 함 - p382
  • SK는 Core Domain이거나 Generic Sub Domain의 일부가 대부분(업무공통, 전체공통 등)
    두 팀 모두 필요한 부분이라면 모델의 어떤 부분이라도 SK가 될 수 있음
    목표는 중복을 줄이고 두 하위 시스템간의 통합을 비교적 용이하게 만드는 것 - p382
  • (SK도 공유한다는 개념적인 말 외에 AG와 같은 특별한 기준이 없음, BC와 마찬가지로, Richardson 등의 기준을 다시 살펴봐야 함)

 

 

Customer/Supplier Development Team (고객/공급자 개발팀)

  • 상류시스템(생산 등의 첫단계)과 하류시스템(소비자에 가까운 마지막 영업활동)은 자연스럽게 두개의 BC로 나뉜다
    상이한 기술을 사용하거나, 구현에 각기 다른 도구 집합이 필요하다면 더욱 그렇다
    (Polyglot을 의미) - p383
  • 두 팀간에 명확한 고객(하류시스템)/공급자(상류시스템) 관계 확립 필요
    하류팀이 상류팀에 대한 고객 역할을 맡게하라
    하류 요구사항에 대한 작업은 협상하고 이에 대한 예산을 책정해서 모든 이들이 일정과 약속을 이해할 수 있게하라 - p384 (MSA에서 서비스간 API First Design을 통해 Provider/Consumer 입장에서 주고 받을 API/PUB/SUB 등의 프로그램을 기본설계를 통해 정의하고 그에 따른 공수나 일정계획 등의 공유를 의미)
  • 결과로 예상되는 (Provider가 노출하는) 인터페이스를 검증할 자동화된 인수 테스트(Acceptance Test) 를 함께 개발하라,
    이 테스트를 상류팀 테스트 스위트에 추가해서 지속적인 통합의 일부로 실행되게하라,
    이 테스트를 토대로 상류팀은 하류시스템에서 발생할지도 모르는 부수효과를 두려워하지 않고 자유로이 코드를 변경할 수 있을 것이다 (자동화 테스트, TDD의 중요성, 하지만 현실은?) - p384
  • 인수 테스트 자동화는 이러한 고객 관계에 필수불가결한 사항,
    이 테스트를 변경한다는 것은 곧 인터페이스를 수정한다는 의미를 내포하므로 테스트를 수정하려면 다른팀과 협의해야 한다- p385 (MSA에서 신뢰할 수 있는 배포 > 자동화 테스트의 필요성과 동일한 맥락)

 

 

Conformist (준수자)

  • 거대한 인터페이스를 제공하는 기존의 컴포넌트를 사용할 경우 일반적으로 해당 컴포넌트에 포함된 모델을 준수(Conform)해야 한다. 팀 조직과 통제에 근거해서 판단하면 컴포넌트와 Application은 의심할 여지없이 서로 다른 BC이므로 소소한 포맷변환을 위한 Adapter가 필요할 수도 있지만 모델은 동일해야한다 - p389

 

 

 

Anti Corruption Layer(ACL, 오류 방지 계층)

  • (ACL의 필요성) - p391 ~ 392
    - 새로운 시스템은 대부분의 경우 자체적인 모델을 보유한 레거시나 타 시스템과 통합돼야한다
    - 레거시 시스템의 모델은 취약하고, 잘 설계된 경우라도 프로젝트에 적합하지 않은 경우가 대부분이다
    - Client와 동일한 모델을 기반으로 하지 않는다 (그래서 IF 테이블 등을 만든다)
    - 레거시는 다른 플랫홈을 기반으로 하거나 다른 프로토콜ㅇ르 사용하는 별개의 시스템과 통신하는 수단 필요
    - 데이터 타입은 우리 시스템의 데이터 타입으로 변환해야 한다
  • 격리계층 정의 필요 - p392
    - 격리계층은 이미 존재하는 인터페이스를 거쳐 다른 시스템과 통신하므로 타 시스템을 거의 수정하지 않아도 된다
    - (시스템 간)두 모델을 상대로 양방향으로 번역 (서로 다른 시스템 또는 모델간의 데이터 매핑 등)
  • ACL
    - 개념적인 객체와 행위를 하나의 모델과 프로토콜에서 다른 모델과 프로토콜로 변환하기 위한 메커니즘
    - ACL의 인터페이스는 보통 Service의 집합으로 표현
    - 시스템간의 상호작용에 필요한 통신 및 전송 메커니즘과 Facade, Adapter, 번역기를 조합하는 것 - p393
    - 그림 14-8 ACL 구조, p395
    - ACL은 두 BC를(또는 두 시스템을) 잇는 수단
  • Facade - p394
    하위 시스템에 대한 Client의 접근을 단순화하고 쉽게 사용할 수 있게 만들어주는 인터페이스에 해당
    타 시스템 기능 접근을 능률화/효율화/단순화하고 그 밖의 (기술, 통신 등) 것은 감출수(캡슐화) 있다
    호출하는 시스템의 모델에 따라 엄격하게 만들어야 함
  • Adapter - p394
    행위를 구현하는 측에서 이해한 것과 다른 프로토콜을 Client에서 사용하게 해주는 Wrapper에 해당
    디자인패턴에서는 Client에서 예상하는 표준 인터페이스를 준수하는 래핑된 객체에 집중
  • 통합이 가치있을수도 있지만, 통합에는 언제나 비용이 많이 든다.
    통합이 정말 필요한 것인지 확인해보는 과정을 거쳐야 한다 - p398
    (MSA처럼 각자의 역할에 충실하며 독립적으로 분산 유지, 개별 서비스를 통합하려면 그만한 사유가 필요)

 

 

'DDD' 카테고리의 다른 글

반버논 DDD Distilled 도메인 주도 설계 핵심  (0) 2021.10.15
15장_디스틸레이션  (0) 2021.10.12
09장_암시적인 개념을 명확하게  (0) 2021.10.07
08장_도약  (0) 2021.10.07
07장_언어의 사용(확장 예제)  (0) 2021.10.07