본문 바로가기
DDD

반버논 DDD Distilled 도메인 주도 설계 핵심

by kooangelo 2021. 10. 15.

 

 

--------------------------------------------------------------

Ch2. BC 및 UL과 전략설계

  • BC내에서 UL을 모델링하는 것
    (업무 전문가들의 해당 도메인에 대한 설명을 개발자와 공유하고 도메인의 언어로 그 내용을 모델링으로 표현)
  • BC
    - 동일한 Context의 범위를 표현
    - 이 Context 범주 내에서 SW 모델의 각 Component는 특정한 의미를 갖고, 특정한 일을 수행한다는 의미
    - BC내 존재하는 Component들은 Context에 특화돼 있으며, Context 안에서 의미가 살아남
    - BC는 모델이 구현되는 곳이고 BC마다 각각 분리된 SW산출물이 나옴
      (BC별로 별도 모델, 설계, 구현, 즉 물리적으로 WAS, DB가 분리됨을 암시)
  • UL
    - 팀 원 모두가 해당 도메인의 특정 표현이 가진 제약사항과 정확한 의미를 이해
    - 이 표현은 개발되는 있는 SW 모델을 정의하는 팀이 사용하는 모든 언어처럼 팀 내에서 보편적이기 때문
    - 나라별로 국경을 경계로 언어가 명확하게 달라지듯, BC는 언어의 경계
      (나라별 언어간의 통역이 필요하듯 BC간의 통역 Translator이 필요) 
    - 보편적 언어라는 것은 SW모델을 소유하는 팀이 이야기할 때 사용,
      이 언어의 대표적인 기록형태는 SW모델의 소스코드
    - 예 : 정책이라는 의미도 다 같은 정책이 아니다. 계약의 정책, 청구의 정책, 검사의 정책이 각 의미가 다르므로
      그래서 계약BC, 청구BC, 검사BC를 경계짓고 그 안에서의 정책은 해당 BC에서만 통용되는 UL이다(p48)
  • 인수테스트에 대한 단위 테스트 기반 접근법을 실행 가능한 명세와 동일한 목적을 달성 - 예 p74
  • 76페이지 아키텍처 그림 > DDD의 Layered Architecture에 적용 가능
    - 각 BC마다 이러한 Layer 존재 (BC마다 개별 Inner Architecture 를 의미)
    - Input Adapter : UI Controller, REST Endpoint, Message Listerner
    - Application Service : Usecase Control, Transaction 관리를 여기서 
    - Domain Model : Domain Biz Logic
    - Output Adapter : Persistence, Message Sender

 

--------------------------------------------------------------

Ch3. Sub Domain과 전략설계

  • 구축 프로젝트에서 완성해야할 시스템 > 여러 BC
    여러 BC중 하나가 Core Domain
    나머지 BC에는 다양한 Sub Domain
  • BC : Sub Domain = 1 : 1
  • Sub Domain
    - 대부분의 비즈니스 Domain은 전체를 포괄적으로 생각하기엔 너무 크고 복잡
    - 그래서 거대하고 복잡한 프로젝트에서 문제 영역을 이해할 수 있도록
      전체 비즈니스 Domain을 논리적으로 쪼갤때 Sub Domain을 사용
    - 전체 비즈니스 Domain 의 하위, 큰 시스템의 복잡도를 해결
       (예 : 쇼핑몰 > 상품, 주문, 채널, 물류 또는 주문 > 고객, 주문, 대외주문, 결제)
    - 하나의 논리적 Domain
    - 명확한 전문 지식 영역별로 정의 > 비즈니스 각 영역에 대해 해결 방안을 제시하는 책임의 소유 관점
    - Sub Domain의 해당 업무를 잘 이해하고 있는 한 명 이상의 도메인 전문가들이 있다는 것을 의미
      이 도메인 전문가는 Sub Domain에 해당하는 BC를 개발하는 팀의 일원
  • Sub Domain의 유형 3가지
    - Core Domain : 시스템내 도메인중 차별화를 만들 영역으로 높은 우선순위, 가장 큰 투자가 필요한 곳
    - Support Sub Domain : 기성 제품으로 해결할 수 없는 맞춤 제작 개발이 필요한 영역, 아웃소싱도 고려 가능
                                    지원 서브 도메인이 없이 핵심 도메인을 성공시킬수 없기 때문에 여전히 중요한 SW 모델
    - General Sub Domain : 기존 제품 구매를 통해 충족 시킬 수 있는 경우, 아웃소싱 및 팀 내 직접 개발도 가능
  • DDD의 Module : Java의 pakcage, C#의 namespace에 해당
  • 87 ㅡ bc : sub domain = 1: 1 하단에 모둘 설명도 있음

 

--------------------------------------------------------------

Ch4. Context Mapping과 전략 설계

  • Context Mapping : 핵심 도메인을 다른 BC와 통합
  • 90페이지 Context Mapping 그림 : BC간의 점선
  • 서로 다른 두 BC안에 각각의 UL이 있는 것을 생각해보면, 이렇게 BC간의 연결된 선은 두 언어 사이의 통역을 의미

 

Context Mapping 의 종류

  • Partnership, 92페이지 그림
    - 각 팀은 BC를 책임지고 의존성을 갖게되어 함께 성공하거나 다같이 실패한다는 의미

    - BC간의 밀접한 관련이 있기 때문에 상호간의 의존적인 작업, 일정 조율, 적절한 통합
  • Shared Kernel 공유커널, 93페이지의 교집합 그림(Partnetship 의 굵은 실선과 달리)
    - 팀 사이의 공통 모델을 공유
    - 공유하는 모델요소에 대해 서로 합의 해야 함
    - 공유하는 모델의 코드, 빌드, 테스트하는 것은 한 팀에서 맡아 수행
    - 팀 사이의 열린 의사소통이 가능해야하고, 지속적인 합의가 필요해서 먼저 처리하기도 관리도 쉽지 않음
  • Customer-Supplier 고객-공급자, 94페이지 그림
    - 공급자 (상류 Upstream)
    - 고객 (하류 Downstream)
    - 고객이 원하는 것을 제공해야 하기 때문에 관계를 주도하는 것은 공급자
    - 다양한 기대를 충족시키기 위해 공급자와 함께 계획하는 것은 고객의 역할이지만,
      고객이 언제 무엇을 받게 될지는 결국 공급자가 결정
    - (Provider/Consumer의 관계와 동일한 개념)
  • Conformist 준수자, 95페이지 그림
    - 상류와 하류팀이 있고, 상류팀(공급자)이 하류팀(고객)의 특정 요구에 지원할 동기가 없는 경우에 나타나는 관계
    - 하류팀이 자기들의 특정 요구에 맞춰 상류 모델의 UL을 계속 변환시키는 것은 쉽지 않기 때문에
      현재의 상류팀 모델을 그대로 따른다 (Provider의 제공에 따라 Consumer가 구현)
    - 예 : 아마존과 제휴하는 판매자 중 하나가 아마존 시스템과 통합하려고 할 때
           아마존 모델을 준수하는 것처럼 확실하게 자리잡은 거대하고 복잡한 모델과의 통합이 필요할 때
  • ACL (반부패계층, 손상방지레이어), 페이지 95 그림 (OHS와 달리 받는 쪽에서 구현)
    - 가장 방어적인 Context Mapping 관계
    - 하류팀(고객, 받는 쪽이) 그들의 UL과 상류팀의 UL 모델 사이에 번역 계층을 만드는 것
    - 이 계층은 상류모델로 부터 하류모델을 독립(보호)시키고 둘 사이를 번역
    - ACL을 적용하여 통합에 용이한 모델 개념을 만들고,
      원하는 형태의 비즈니스 요구도 맞추고,
      외부의 이질적인 개념으로부터 독립성 유지,
      이런 경우 서로 다른 언어로 말하는 두 팀 사이를 번역하는 번역가를 고용한 것과 같은 효과
  • OHS Open Host Service 공개 호스트 서비스, 페이지 96 그림(ACL과 달리 제공하는 쪽에서 구현)
    - BC에 대한 접근을 제공하는 프로토콜이나 인터페이스를 정의
    - 프로토콜은 이 BC와 통합하고자 하는 모두가 용이하게 사용할 수 있도록 '공개' 돼 있음
    - API로 제공하는 서비스는 문서화가 잘 돼 있고 사용하기 좋음
    - 통합이 필요한 경우 받는 쪽이 ACL을 만들지 못해도
      OHS를 제공하는 BC의 준수자가 되는것이 수많은 레거시들을 맞닥뜨리는것 보다 괜찮은 선택
      (여러 시스템의 기능을 사용해야하는 경우 유리하다는 의미, ACL등으로 일일이 내가 구현하기 보다는)
  • 공표된 언어 PL, Published Language, 페이지 97 그림
    - PL : 간단한 사용과 번역을 가능하게 하는 문서화된 정보 교환
    - XML, JSON 처럼 최적화된 작성 형식으로 정의
    - OHS는 서드파티에게 최상의 통합 경험을 줄 수 있는 PL을 제공 (OHS + PL 함께 생각해야한다는 의미)
  • 각자의 길 Sperate Ways, 페이지 98 그림
    - 여러 UL, BC를 사용, 통합하는 것이 유의미한 결과를 제공하지 못하는 상황
    - 내가 찾는 기능을 다른 UL에서 완전히 제공하기 어려울 수 있기 때문에
      본인 BC내에서 이를 위한 해결 방안을 별도로 만들고 통합하지 않음
  • 큰 진흙 덩어리 (기존 Monolith 처럼 뒤엉켜 있는 시스템)
    - 큰 진흙 덩어리를만드는 일은 기를 쓰고 피해야 함(Monolith를 더 이상 뚱뚱하게 만들지 말자의 의미와 동일)
    - 더 큰 진흙 덩어리를 만들게 되면
     1) 부족절한 연결과 의존으로 이핸 문제가 확산
     2) 큰 진흙 덩어리 일부를 관리할 때 '두더지 잡기' 처럼 한가지 문제가 해결돼도 또 다른 문제를 야기
     3) 오직 전반적인 지식과 모든 언어를 다룰 수 있는 영웅 같은 사람이 있어야 시스템의 붕괴를 막을수 있음
        (기존의 Monolith 전체를 아는 사람은 없음)
    - 페이지 100 그림과 같이 기존 Monolith로 부터 ACL 등을 통해 내 모델을 언어를 BC를 보호해야함
      그렇지 않으면 내가 만드는 모델도 이해할 수 없는 늪에 빠지게 될 것이다
      무슨 일이 있어도 기존의 그 언어를 섞어 쓰면 안 된다 (기존 모델/코드와 혼용되면 안된다는 의미)

 

Context Mapping 활용, 페이지 101 그림

  • BC간의 통합시 어떤 인터페이스를 제공할 것인가?
    SOAP RPC, RESTfull HTTP, Messaging Publisher-Subscrib (견고한 통합 방법 순서) 가 일반적이고
    DB 통합을 강요 받을 수도 있는데, 그런 일은 없길 바란다, DB통합은 진짜 피해야 한다
    그럼에도 불구하고 DB를 통합해야한다면 ACL을 이용해서 여러분 모델을 독립시켜야 함
    (DB를 통합한다는 의미는 서로의 모델, UL이 뒤엉킴을 의미하는 듯)
  • 1) SOAP을 이용한 RPC (Remote Procedure Call), 페이지 102, 103 그림
    - 다른 시스템의 서비스를 이용할 때 마치 로컬 프로시저나 메서드를 호출하는 것처럼 사용한다는 개념
    - 요청 > 원격 시스템에 요청 전달 > 성공적 수행 > 네트워크를 통한 결과 반환의 과정을 보장해야 함
    - 통합 수행 시점에 예기치 못한 네트워크 장애나 지연의 가능성을 동반
    - 그러므로 Client BC와 Service BC사이의 강한 결합을 의미
    - 제대로 동작하기만 한다면 통합하기에 좋은 방법이지만
      주된 문제는 호스팅하는 시스템에 문제가 발생하면 Client 호출은 에러 결과를 받은채 실패 > 견고함이 떨어짐
      사용하기 쉬원 보인다고 속으면 안 됨
    - API가 있든 없든, 원치않는 외부의 영향으로부터 자기의 BC를 분리할 필요가 있다면 ACL 정의 필요
  • 2) RESTful HTTP, 페이지 104 그림
    - BC간의 교환되는 리소스뿐만 아니라, POST/GET/PUT/DELETE 4가지 주요 Operation 관여
    - 분산 Computing에 적합한 API들을 정의하는데 도움
    - 인터넷과 웹의 성공으로 인해 이런 주장은 좀 더 설득력을 갖게 됐음
    - REST 인터페이스를 제공하는 서비스BC는 OHS + PL을 제공해야 함
    - 네크워크나 서비스 제공자의 장애 또는 예기치 않은 지연 등 RPC에서의 실패 원인과 동일한 사유로 실패 가능성
    - REST를 사용할 때 저지르는 흔한 실수는 도메인 모델안에 직접적으로 Aggregate를 반영하는 리소스 설계하는 것
      이렇게 하면 모든 Client에게 준수자 관계를 강요하면서
      모델 변화가 리소스의 형태에 영향을 줌 (Provider 가 노출하는 API In/Out 등에 흔들린다는 의미)
  • 3) Messaging, 페이지 106, 108, 109, 110 그림
    - Message교환에서 지연 가능성을 이미 알고 있기 때문에 실시간 결과가 필수적이지 않을 때 이용
    - RPC나 REST와 달리 분절된 형태와의 일시적인 결합을 대부분 제거할 수 있기 때문에 가장 견고한 형태
    - BC내 AG는 Domain Event를 만들 때 관심 있는 다른 Context들은 발생된 이벤트를 사용
    - 즉, 구독 BC가 Domain Event를 받으면, 이벤트의 형태와 값을 토대로 동작 수행
    - 이때 소비(Consumer)하는 BC안에 새로운 AG를 생성하거나 기존 AG를 수정해야할 때가 있음
       (Subscriber가 Event를 수신해서 본인에게 필요한 데이터를 생성하거 (상태 등)수정할 수 있음)
    - 소비자는 이벤트 발행자의 이벤트 형태(예 : 클래스)를 그대로 사용하면 안 됨(그러면 Conformist)
      오직 Event Schema, 즉 PL에만 의존해야 함
      Event가 JSON 또는 Simple Object Format으로 발행되면,
      소비자는 그것들을 Parsing해서 데이터 속성들을 얻은 후 이벤트를 처리해야함
    - At-least-once delivery (적어도 한번의 전달)
      메시징 매커니즘이 특정 메시지를 주기적으로 재전달하는 메시지 패턴
      메시지 손실, 느린 반응, 수신자 장애, 수신자가 수신 사실을 알리는데 실패하는 상황에서 적용
      발송자가 다 한 번 메시지를 전달했더라도 메시지는 어려 번 전달될 수 있다
    - 멱등 수신자 Idempotent Receiver
      수신자가 Operation을 수행하는 방식, 오퍼레이션이 어려 번 수행되더라도 동일한 결과가 되도록 만드는 방식
      수신자가 중복제거, 반복 메시지 무시 또는 이전에 전달된 메시지의 결과와 정확히 동일한 결과가 되도록
      오퍼레이션 재수행을 안전하게 처리한다는 것을 의미
    - 메시징 매커니즘은 항상 비동기 요청-응답 통신을 사용하기 때문에 어느 정도의 지연은 일반적이고 당연
    - 서비스가 종료되기 저에는 서비스에 대한 요청이 절대(겅의) 막힐 일이 없기 때문에
      어느 정도의 지연 발생을 감내할 수만 있다면, 전체 솔루션을 견고하게 만들수 있다는 것을 의미

 

Context Mapping 사례, 그림 112, 113

  • 계약심사BC에서 정책 컴포넌트가 만들어지면, 정책 발행이라는 이름의 도메인 이벤를 발생
  • 메시징 구독을 통해 이를 제공받은 다른BC들이 이 도메인 이벤트에 반응할 때
    구독BC안에 이 정책에 상응하는 정책 컴포넌트를 만들수도 있다
    (컴포넌트 객체를 통해 구독BC내 DB에 데이터 생성/수정을 의미)
  • 정책 발행 도메인 이벤트는 정책의 식별성, 정책ID를 통해 식별
  • 구독BC에 생성된 모든 컴포넌트는 발신 주체인 계약심사BC로의 역추적을 위해 그 식별자를 보유
  • 정책발행 도메인 이벤트가 제공하는 것 이상의 정책 데이터가 필요하면, 구독BC는 언제든지 계약심사BC로부터 더 많은 정보를 가져올 수 있다(구독BC는 발행BC에서 쿼리를 수행(API등으로)하기 위해 정책발행ID 사용)
    (이벤트는 아이디등 주요속성만 전달하고 상세가 필요하면 에이피아이로 하는것도 장점)
  • Domain Event(DE)에 모든 정보를 담는 것과 키를 포함한 주요 속성만 받고 다시 쿼리하는 것과의 장단점
    - 1)모든 소비자를 만족시키기 위해 도메인 이벤트에 충분한 데이터를 모두 담아야 할 때도 있음
    - 2)반면에 DE를 가볍게 유지하고 소비자가 더 많은 데이터를 요청할 때 다시 가져오는 것이 유리할 때도 있음
    - 여러 소비자들의 DE에 요구할 모든 데이터를 예측하는 것이 어렵고,
      모두 제공하려면 너무 많은 것을 담아야 할 수 있음(예 : 너무 많은 정보를 제공함에 따라 보안적인 측면의 문제)
    - 이런 경우 가벼운 DE와 소비자들이 요청할 수 있는 풍부한 쿼리(API 등)를 설계하는 것이 적합
    - 물론 이 두가지 경우 1) 2) 를 혼합도 가능
  • 115 그림, 계약심사BC에서 재쿼리를 어떻게? 계약심사BC에 RESTful OHS와 PL 설계
    Client 입장에서는 구독한 이벤트로 부터 ID를 추출해서 간단한 HTTP GET와 ID로 정책 상세 데이터 검색 가능

 

--------------------------------------------------------------

Ch5. Aggregate과 전술 설계

  • 120페이지 그림
    BC : AG = 1 : N
    BC : VO = 1 : N
  • Entity, 121페이지 그림
    - 유일성, 독립성
    - 특성을 구별할 수 있는 고유한 식별성을 갖음
    - 상태가 계속 변함
  • Root Entity
    - AG안의 다른 모든 요소를 소유
    - Root Entity의 명칭은 AG의 개념적인 명칭
  • VO, Value Object
    - 불변의 개념적 완전성
    - Entity와 달리 공유한 식별성이 없음
    - 값 형태로 캡슐화된 속성을 비교함으로써 동일함이 결정
    - VO가 어떤 것을 나타낸다기 보다는 Entity를 서술, 수량화, 측정하는데 사용
  • Aggregate
    - AG : Entity = 1 : N, 1개 이상의 Entity로 구성
    - 그 중 한 개 Entity는 Root Entity
    - AG구성에 VO를 포함할 수 있음
    - 일관성 있는 Tx경계
       Tx제어가 DB에 Commit될 때, 한 AG내의 모든 구성요소는 반드시 비즈니스 규칙을 따르면서 일관성 있게 처리
    - 비즈니스 규칙은 단일 Tx을 마쳤을 때, 어떤 것이 전체적으로 완전하게 그리고 일관성 있게 처리돼야할지를 결정

 

AG의 경험 법칙

  • 규칙 1) AG경계 내에서 비즈니스 불변사항들을 보호하라
    - Tx이 Commit될 때 비즈니스의 일관성이 지켜지는 것에 기반을 두고 AG구성요소를 결정
    - 예 : Task의 남은시간이 '0'일때, BackLogItem의 상태는 반드시 'DONE'으로 설정해야한다라는 업무 규칙
      이는 Tx후 반드시 부합돼야 하는 명확한 비즈니스 불변사항이고, 비즈니스 요청(요구) 사항이다
  • 규칙 2) 작은 AG를 설계하라
    - 각 AG의 메모리 사용햘과 Tx범위가 비교적 작아야 함을 강조
    - 작은 AG로 구성했을 때 빠르게 로그되고, GC도 빠르다
    - 연관된 각 작업이 한 명의 개발자가 관리할 수 있을만큼 작기 때문에, AG가 쉬워지고, 테스트도 용이
    - AG의 핵심은 SRP (Single Responsibility Principle) 이라는 단일 책임 원칙
    - AG가 너무 많은 일을 한다면, 이후 AG크기에 대해 재논의할 가능성이 크다
  • 규칙 3) 오직 식별자로만 다른 AG를 참고하라
    - 식별자만을 통해 Reference할 때 이점은 AG을 RDB, Document DB, Key/Value Repository 와 같은
      다른 형태의 저장 매커니즘으로 쉽게 저장할 수 있다는 점
  • 규칙 4) 결과적으로 일관성을 사용해 다른 AG를 갱신하라
    - DE는 AG에 의해 발행되고, 관심있는 BC는 이를 전달 받음
    - 관심있는 BC는 DE를 발행한 동일한 Context일수도 있고, 다른 BC일수도 있음

 

AG 모델링

  • 빈약한 도메인 모델
    - 객체지향 도메인 모델을 사용하면서,
      AG가 업무 행위 Operation이 아닌 읽고/쓰는(getters/setters) 공개 접근자만 갖는 경우
      (우리의 일반적인 VO 와 같은 모델)
    - 업무보다는 기술적인 부분에 초점을 맞췄을 때 발생하는 경향
    - 이러한 빈약한 모델은 도메인 모델이 주는 혜택을 받지 못하고, 모든 오버헤드를 떠안아버리는 상황
    - 업무로직이 도메인 모델을 넘어 Application Service까지 새어 나가지 않도록 주의 필요
    - 업무로직을 Helper나 Utility 클래스에 위임하는 것은 원하는 대로 잘 동작하지 않음
       Service Utiltiy는 정체성에 혼란을 주고, 요구사항을 올바르게 유지시키지도 못함
  • 1) AG Root Entity 생성, 페이지 138 그림
    2) AG를 찾는데 필요한 본질적인 속성아니 필드들을 찾기(예 : name, description)
    3) Operation 추가
  • 추상화를 조심스럽게 선택하라
    - 높은 수준의 추상화 구현이라는 덫에 현확되지 말자
    - 팀이 정의한 도메인 전문가의 멘탈 모델에 따라 보편언어를 모델링해야함
  • 올바른 크기의 AG
  • 테스트 가능한 단위
    - 단위 테스트를 위해 AG를 철저하게 캡슐화되도록 설계하자
    - 복잡한 AG는 테스트하기도 힘들다

 

 

--------------------------------------------------------------

Ch6. 도메인 이벤트(DE)와 전술 설계

  • DE는 BC내 업무관점에서 중요한 사항들에 대한 기록
  • 인과관계 요청의 예
     - A 지갑을 잃어버렸어, B 큰일났네, A 걱정마 지갑을 찾았어, B 잘됐다
    - 이 메시지들이 인과관계 요청이 아닌 형태로 분산된 노느에 전달된다면
      예 : 지갑을 잃어버렸어 > 잘됐다 라는 이상한 형태로 메시지가 전달될 수 있음
    - 예와 같이 인과관계가 적절하게 맺어져 있지 않다면 전체 도메인 상황이 잘못되거나 혼란스러워짐
    - 전술설계를 통해 DE가 도메인 모델에 구체화되고, DE가 만들어지면 BC와 다른 자원들은 이 이벤트를 받아 활용
    - 이는 중요한 이벤트에 관심이 있는 이벤트 리스너들에게 관련 상황의 발생을 알리는 매우 강력한 방법
  • DE 설계, 구현, 사용
    - 일반적으로 DE가 발생할 때 그 날짜와 시각을 전달 (예 : Date OccurredOn property)
    - DE에 어떻게 이름을 붙일것인지 주의 필요 > DE에 사용되는 단어들은 도메인 모델의 UL를 반영해야 함
    - 도메인 모델 안에서 발생하는 사건과 모델 밖을 이어주는 다리 역할
    - 이 다리들은 이벤트를 통해 모델들이 원활히 의사소통하는 데 필수적인 역할
    - Domain Event Type 의 이름은 과거에 발생한 것을 서술하므로 과거형 동사로 표현
      예 : ProductCreated, ReleaseScheduled, SprintScheduled, BacklogItemPlanned, BackLogItemCommitted
      각 이름들은 도메인에서 발생한 사건을 명확하고 간결하게 서술
    - Application 에서 Command가 Event를 발생시킨다
      예 : CreateProduct (Command) > ProductCreated (Event)는 명령의 결과  
    - Domain Event이 Property, 156페이지 그림
      DE는 EVent가 만들어지는 시점에 Command가 제공하는 모든 Property를 담고 있어야
      이벤트 구독자들에게 그 모델 안에서 무슨 일(Product가 생성됐다)이 벌어졌는지 정확하게 알릴수 있음
    - Event는 도메인에 주목할 만한 무언가가 발생했다는 것을 다른 모두에게 알리는 방법
    - 일반적으로는 UI에 의한 사용자 기반 명령으로 이벤트 발생
      때로는 마지막 영업일 처럼 시간 만료 등의 (배치)에 의한 이벤트도 발생
    - 예를 들어 '회계연도종료'라는 상황은 비즈니스가 반응해야하는 중요한 이벤트이고 UL의 일부여야 함
      오후4시 '장종료' 이벤트
  • 이벤트 소싱, 162 페이지 그림
    - Event Sourcing : AG 인스턴스에 대해 변경된 것에 대한 기록으로, 발생했던 모든 DE를 저장하는 것
    - AG 상태 전체를 저장하는 대신, 발생했던 각 도메인 이벤트 모두를 저장
    - AG 인스턴에 발생했던 모든 DE를 발생한 순서대로 이벤트 스트림에 구성
    - 반대로, AG 이벤트 스트림을 재적용하면 저장된 정보가 메모리로 환원됨
      이벤트 소싱을 사용하면 메모리에서 삭제됐던 AG들을 이벤트 스트림을 통해 온전히 환원시킬 수 있음
    - Event Repository는 모든 DE를 추가하는 순차적인 Repository Collection 또는 Table을 말한다
    - Event Store는 오직 추가만 가능
    - Event Sourcing을 가장 큰 장점 중 하나는
      핵심 도메인에서 계속 발생하는 모든 기록을 개별적인 발생 수준으로 저장한다는 점
      (기존 상태 변경 이력 테이블 또는 Audit Log 등 과 무엇이 다른가?)
    - 장점의 예 : 법적 기준에 대한 준수 및 분석, 코드 디버깅이나 이벤트 사용 추세 조사 가능
    - ES을 사용하면 CQRS를 사용해야 한다

 

 

--------------------------------------------------------------

Ch7. 가속화와 관리도구

 

이벤트 스토밍(ES)

  • ES는 빠른 주기의 학습과정에 도메인 전문가와 개발자 모두가 참여하는 신속한 설계 기술
  • 명사나 데이터보다 비즈니스와 비즈니스 프로세스에 초점을 맞춤
  • 이를 Event Driven Modeling 이라고 부르는 기술을 사용
  • EDM 은 대화, 시나리오 구체화, 매우 경량화된 UML을 사용한 이벤트 중심 모델링과 연관
  • UML을 아주 조금이라도 능숙하게 이해하고 사용할 수 잇는 비즈니스 측 사람은 거의 없다
    따라서 대부분은 모델링 영역의 몫으로 남아서
    UML의 기본을 이해하고 있는 개발자나 혹은 내가(모델러 등)가 수행해야 했다
  • 나는 몇 년전, 다른 형태의 이벤트 주도 모델링을 경험했던 '알베르토 브란돌리니' 로부터 처음 이벤트 스토밍에 대해 배웠다. 알베르토는 UML대신 포스트잇을 사용, 회의실 안의 모든 사람이 프로세스에 직접 참여해서 빠르게 학습하고  SW를 설계하는 방법의 시초였다. 이 방법이 주는 이점은 아래와 같다
    - 구체적인 접근법
    - 포스트잇과 펜을 갖고 학습 및 설계
    - 업무 전문가와 개발자 모두가 함께 같은 곳에서 학습하고 UL을 함께 만들어 감
    - 클래스나 DB가 아닌(즉, 기술적인 용어를 말할 필요가 없음) 업무 이벤트와 프로세스에 집중
    - 매우 시각적인 접근법
    - 코드를 제외시키고 모두 설계 프로세스의 초반부터 참여
    - 빠르고 적은 비용으로 수행
    - 말 그대로의 거친 표현으로, 폭풍처럼 새로운 핵심 도메인을 몇 주가 아닌 수시간내에 만들어낼 수도 있음
    - 팀은 이해의 폭을 획기적으로 증진시킬 수 있음
    - 미팅을 통해 업무에 대한 이해의 폭을 넓힐 뿐만 아니라 비즈니스 프로세스에 대한 새로운 통찰을 느낄 수 있음
    - 모델과 모델을 이해하는 데 문제가 있다면, 이를 가능한 한 앞 단계에서 빠르게 인지할 수 있음
    - 오해를 바로잡고 그 결과를 새로운 통찰로 활용, 이러한 모든것을 회의실 안의 구성원 모두가 혜택받음
    - 큰 그림과 설계 수준 모델링 모두에 ES를 사용할 수 있음
    - 큰 그림 수준의 스토밍을 하는 것은 비교적 덜 정확하겠지만(예 : Pivotal ES),
      설계 수준 스토밍은 명확한 SW산출물로 이어짐
    - ES을 반복해서 확장하고 정제,
      그렇게 3~4일 보내면 핵심 도메인 그리고 주변의 서브 도메인과의 통합에 대한 깊은 이해
    - 도메인 전문가, 개발자 모두가 질문하고 답을 한다. 서로가 서로를 지원하고, 세션동안 같은 회의실에 있어야 한다
    - 엄격한 평가로부터 자유로운 열린 마음을 가져야 한다
      내가 ES동안 봤던 가증 큰 실수는 사람들이 너무 빨리 지적하려는 것이다
    - 이벤트가 적은것보다 많은 것이 낫다. 더 많은 것을 배울수 있고, 정제할 시간 충분, 정제는 빠르고 비용도 적다
    - 포스트잇에 너무 많은 것을 적을 필요는 없다. 보통 단어 몇 개 정도를 적는다
  • ES 진행 순서, 174페이지 그림 이후 페이지 이어서 연결
    - 일련의 도메인 이벤트를 포스트잇에 적으면서 비즈니스 프로세스를 도출(오렌지색을 사용하면 눈에 잘 띄기 때문)
    - 데이터와 데이터의 구조가 아닌 비즈니스 프로세스에 최우선적으로 초점
    - 포스트잇에 각 도메인 이벤트의 이름을 적어라, 이름은 과거형 예 : ProductCreated, BackLogItemCommitted
    - 포스트잇을 시간 순서대로 붙여라, 왼쪽에서 오른쪽으로 도메인에서 발생하는 이벤트의 순서
    - 동시에 발생하는 이벤트는 같은 시점에 발생하는 이벤트 아래에 위치
    - 이렇게 스토밍 세션을 진행하면서 기존 또는 신규 프로세스의 문제점을 찾아낼 수 있다
      문제점은 자주색 포스트잇에 왜 그것이 문제인지 설명하는 문장을 적어 명확하게 표시
      (기존 주황색읠 Pain Point 및 개선사항)

    - 각 도메인 이벤트를 생성하는 Command 정의(하늘색 포스트잇)
    - 주로 사용자 행위의 결과로 명령이 만들어 지는데, 그 명령이 수행되면서 이벤트가 생성된다
      예 : CreateProduct, CommitBackLogItem
    - Command 포스트잇을 그 명령이 만드는 도멩니 이벤트 왼쪽 옆에 붙인다
      이들은 명령/이벤트, 명령/이벤트... 처럼 서로 짝을 지어 관계를 형성
      (Command는 User에 의한것 뿐 아니라 배치와 같이 System에 의한 Command도 있다)
    - Action을 수행하는 특정 사용자 역할이 있고 이를 명시하는 것이 중요하다면
      작고 밝은 노란색의 포스트잇에 사람이 그 역할의 이름을 적어 Command포스트 왼쪽 하단에 붙여라
      (Actor, 예 : 제품 책임자)
    - Command를 Entity/AG과 연관시키자.
      Entity/AG는 Command가 실행된 후 도메인 이벤트의 결과가 저장되는 데이터 저장소
      이러한 작업을 한 후 ERD는 나중에 그리자. 데이터 보다는 프로세스에 좀 더 집중해야기 때문
    - 업무전문가들이 AG라는 단어를 이해하지 못하면(당연히 이해 못한다) Entity 또는 그냥 데이터라고 불러도 됨
    - 중요한 점은 포스트잇을 통해 AG를 나타내는 개념에 대해 팀이 명확하게 의사소통할 수 있으면 됨
      예 : 노란색 포스트잇 Product, BackLogItem 처럼 명사
    - 서로 다른 업무 전문가들이 같은 용어에 대해 서로 다른 정의를 갖거나
      개념이 중요하긴하나 핵심 도메인의 일부가 아닌 부서들 등을 바탕으로 경계를 찾자
    - BC는 실선, 서브 도메인은 점선으로 표시, 분홍색 포스트잇으로 그 영역을 표시(페이지 182 그림)
      분홍색 포스트잇에 BC명 적기
    - BC간의 이벤트 흐름의 방향을 보기 위해 화살표를 선을 긋자
    - 사용자들이 Action을 수행하기 위해 필요한 다양한 뷰들을 식별, 사용자들의 주요 역할을 파악
      모든 뷰(초록색)을 표시할 필요는 없고, 중요하거나 특별한 뷰를 중심으로

 

애자일 프로젝트에서 DDD관리

  • 프로젝트를 시작할 때 가장 좋은 것 중 하나는 ES을 사용하는 것이다
  • ES를 사용해도 완벽해 질 수 없다. 비즈니스와 비즈니스에 대한 사람들의 이해가 시간이 흐르면서 바뀌고, 
    도메인 모델 또는 바뀔 것이기 때문이다.

 

어떻게 구현해야 하는가?

  • 구체적인 시나리오와 ES는 함께 사용해야하는 2개의 도구다
  • 짧은 ES 세션을 수행. 모델링 관련해 발견한 사항들을 대해 좀 더 구체적인 시나리오를 개발
  • 개선해야할 구체적인 시나리오에 대해 논의, 논의를 통해 SW모델을 어떻게 사용할지 파악
  • 각 시나리오를 수행할 일련의 인수 테스트를 만든다
  • 컴포넌트에 테스트/명세를 수행시킨다
    업무 전문가의 기대에 맞게 수행될 때 까지 테스트/명세, 컴포넌트를 정제하며 짧고 빠르게 반복

 

도메인 전문가와 상호 작용하기

  • DDD를 적용할 때 큰 어려움중 하나는 도메인 전문가와 지나치지 않게 적절한 시간을 갖는 것이다
  • (대부분 Fulltime 참석이 어렵기 때문에) 가급적 중요한 내용으로 제한해서 유용한 시간을 만들어야한다
  • '언제 도메인 전문가와의 시간이 필요한가? 그들이 개발자들을 도와줘야 하는 작업은 무엇인가?'
    - ES활동에는 언제든 도메인 전문가를 포함시킨다
    - 논의와 모델 시나리오 생성에 도메인 전문가의 의견이 필요하다
    - 도메인 전문가는모델의 정확성을 확인하는 테스트를 검토할 때 필요하다
    - 팀 전체가 결정한 UL, AG, Command, Domain Event를 개선하기 위해 도메인 전문가가 필요하다.