# Event Storming 모든 인프라 및 시스템 옵션을 클라우드로 이전할 수 있는 것은 아닙니다. 많은 독점 및 레거시 시스템에도 동일하게 적용됩니다. 그들 중 일부는 처음부터 완전히 재구축될 때까지 클라우드로 이동할 수 없습니다. 그렇다고 해서 이러한 시스템이 그대로 유지되어야 한다는 의미는 아닙니다. ![](https://hackmd.io/_uploads/SkiBhYEP2.png) 레거시 소프트웨어 드래곤을 처리하는 가장 좋은 방법은 클라우드를 위한 소프트웨어를 만드는 방법을 이해하는 것입니다. 기존 처리 시스템 및 데이터저장소를 분석하고 새 시스템 사용에 대한 직원 교육과 병행하여 여러 단계로 나누어 클라우드로 이동하는 것입니다. ## 이벤트 스토밍이란 무엇입니까? 이벤트 스토밍은 모놀리스를 분해하고 새로운 이벤트 기반 마이크로서비스 버전을 개발하기 위한 명확하고 일관된 접근 방식을 설정하는 효과적인 접근 방식입니다. 기본 아이디어는 소프트웨어 개발자와 도메인 전문가를 모으고 서로가 서로에게 배우는 것입니다. 일반적으로 대화형 워크숍으로 제공되며 DDD(Domain Driven Design) 원칙을 활용합니다. 모든 기술 또는 비즈니스 도메인, 특히 규모가 크거나 복잡하거나 둘 다인 도메인에 실질적으로 적용할 수 있습니다. ## 누구를 위한 것입니까? Event Storming은 소프트웨어 개발 팀에만 국한되지 않습니다. 실제로 Event Storming 워크샵에 개발자, 도메인 전문가, 비즈니스 의사 결정자 등 모든 이해 관계자를 초대하여 각 참가자의 관점을 수집하는 것이 좋습니다. ## 이벤트 스토밍 방법 스티커를 붙일 수 있는 넓은 벽을 활용합니다. ![](https://hackmd.io/_uploads/Hy6SojBwn.png) 스티커 메모에는 5가지 이상의 고유한 색상이 필요합니다. 첫 번째 단계는 도메인 이벤트를 찾아 주황색 스티커 메모에 써서 벽에 붙이는 것입니다. 충분한..(모든) 도메인 이벤트가 발견되면 두 번째 단계는 각 도메인 이벤트를 발생시킨 명령(Command)을 찾는 것입니다. 명령은 파란색 메모에 기록되며 해당 도메인 이벤트 바로 앞에 배치됩니다. 세 번째 단계에서는 명령이 실행되고 이벤트가 발생하는 어그리게이트를 식별합니다. 어그리게이트는 노란색 스티커로 작성됩니다. 네 번째 단계에서는 식별된 어그리게이트의 관계에 따라 경계를 나누어 제한된 컨텍스트를 형성합니다. 마지막으로 컨텍스트의 관계를 설정하고 컨텍스트 맵을 만듭니다. ## 이벤트 스토밍 용어 ![](https://hackmd.io/_uploads/BJkjrvSPh.png) 이 다이어그램을 살펴보겠습니다. 여러 목적을 가진 다른 색상의 스티커가 있습니다. 우리가 DDD시간에 배운 Aggregate, Command, Domain Event, View를 떠올려봅시다. - <font color=#ff9133>Domain Event / 도메인 이벤트(주황색 스티커 메모) - 무슨 일이 일어났는지 설명합니다. 특정 비즈니스 맥락에서 발생한 사실을 과거형으로 표현</font> - <font color="#ffe333">User/Actor 사용자 (노란색 스티커 메모) - View를 통해 Command를 실행하는 사람</font> - <font color='#28ABE3'>Command / 명령(파란색 스티커 메모) - 도메인 이벤트를 유발한 작업을 설명합니다. 역할이나 시간 또는 외부 시스템에 의해 제기된 요청이나 의도입니다.</font> - <font color='#50c878'>Information / 정보(녹색 스티커 메모) - Command을 내리는 결정을 내리는 데 필요한 지원 정보를 설명합니다.</font> - <font color="#EBC072">Aggregate / Consistent Business Rules / 어그리게이트(노란색 스티커 메모) - 특정 비즈니스 기능을 나타내는 이벤트 또는 작업 그룹 - 명령의 의도를 수락하거나 이행할 책임이 있습니다. - 범위가 작아야합니다. - 최종 일관성으로 전달</font> - <font color='#7F44B0'>Business Process / Policy / 비지니스 프로세스 (라일락 스티커 메모) - 비즈니스 규칙 및 논리에 따라 명령을 처리합니다. - 하나 이상의 도메인 이벤트를 만듭니다.</font> - <font color='#e433d6'>External System / 외부 시스템 (분홍 스티커 메모) - 결제 게이트웨이나 배송과 같은 타사서비스 </font> :::info 이 범례는 이벤트 준비자가 사전에 작성해 놓을 것입니다. ::: ## 간단한 이벤트 스토밍 예제 Event Storming을 처음 사용하고 도메인 이벤트 탐색 여정을 시작하는 방법을 모르는 경우 다음을 생각해 볼 수 있습니다. 오늘 아침에 눈을 떴을 때부터 오늘 회의에 참석하기위한 지금까지 모든 이벤트를 생각해 보세요. 목록을 작성하고 각 이벤트를 주황색 스티커 메모에 넣습니다. ![](https://hackmd.io/_uploads/Sy8W3END2.png) 무슨 일이 있었는지 설명하려면 과거 시제를 사용해야 합니다. 그리고 이것은 모두 "실제 일어난 일" 입니다. ### 우선 순위 파악하기 이제 여기에 추가적인 사건을 생각해보겠습니다. 만약 오늘 회의가 늦었다고 상상을 해볼까요? 위 타임라인에서 전체 시나리오를 완료하기위해 가장 필수적인 이벤트는 무엇인가요? 위 이벤트들은 "회의 참석"을 위한 중요한 경로입니다. 그리고 이것을 소프트웨어 개발로 전환해볼까요? 제품 소유자가 제품 백로그에 희망기능을 푸시할 때 우선 순위를 어떻게 정하시겠습니까? 이런식으로 스토리를 다듬고 작업의 우선순위를 정할 수 있습니다. 다음으로 조금 더 복잡한 시나리오를 살펴보겠습니다 # Cafe business 시나리오 간단한 시나리오를 통해 Event Storming을 해보겠습니다. ![](https://hackmd.io/_uploads/H1M1uvVD2.png) 카페에서 커피를 한잔 하고자합니다. 여러분은 카페에 입장합니다. ![](https://hackmd.io/_uploads/rJwDOvND3.png) 카페에 다양한 메뉴가 있습니다. 음료와 케익, 커피가 있습니다. 카운터직원이 당신에게 인사를하고 여러분은 카페의 메뉴를 보고 아이스아메리카노와 티라미수를 주문하였습니다. 자리를 안내하고 잠시 후 커피가 나왔습니다. ![](https://hackmd.io/_uploads/Sk64muSvh.png) 많은 자리에 사람들이 있었고 당신은 4인용테이블로 안내받았습니다. ![](https://hackmd.io/_uploads/Bk0UX_SPh.png) 카운터직원이 받은 주문을 보고 바리스타가 커피를 만들었습니다. 웨이터는 티라미수를 한조각 꺼내 접시에 셋팅한 후 바리스타가 만든 커피와 함께 당신에게 가져다 주었습니다. ![](https://hackmd.io/_uploads/BJwStiBPh.png) 당식은 커피를 다 마시고 자리에서 일어났습니다. 웨이터는 당신의 자리를 정리하고 당신은 카페를 떠났습니다. # 역할(Roles), 명령(Commands)과 이벤트 매핑(Events Mapping) ## 카페의 주요 비지니스 이벤트 :::info 비지니스 시나리오에서 이벤트를 찾을땐, 도메인 전문가는 기술적인 수도 아닐 수도 있습니다. 유비쿼터스 언어를 사용하여 동일한 이해에서 이야기하세요. ::: ### 첫번째 라운드 - 도메인 이벤트 수집 각 참가자는 오렌지색 포스트잇만 사용하여 카페에서 생성되는 이벤트를 작성하여 붙여넣습니다.이벤트 발견 프로세스는 기술적이지 않습니다. 핵심 비지니스 가치에 집중하고 트리거와 결과를 파악하는데 집중하세요. 이벤트는 사실입니다. 이미 발생했기 때문에 과거형의 시제를 사용합니다. 아마도 결과는 아래와 비슷할 것입니다. ![](https://hackmd.io/_uploads/SkGHe9Vwn.png) - 메뉴 제공 - 아메리카노, 티라미수 주문함 - 결제완료함 - 영수증 발행함 - 좌석 할당함 - 커피 준비함 - 티라미수 준비함 - 고객 떠남 - 자리 정리함 ### 두번째 라운드 - 도메인 이벤트 세분화 참가자들에게 각 이벤트가 무엇을 의미하는지 설명하도록 요청하십시오. 구문의 정확성을 확인하십시오. 그리고 이 이벤트를 발생한 순서에 따라 순차적으로 정렬 합니다. 이 과정에서 누락된 이벤트도 같이 식별합니다. ## 명령 및 이벤트 매핑 ### 세번째 라운드 - 원인 추적하기(프로세스 모델링) 이제 이벤트가 발생한 원인을 찾아야합니다. 이 이벤트가 왜 발생했는지를 찾아야합니다. 크게 네가지 종류가 있습니다. - 사용자 작업(Command,User/Actors,View/Read Model) - 외부 시스템(External System) - 비지니스 프로세스(Business Process) - 다른 도메인 이벤트( 자동화 등..) 하나씩 살펴보겠습니다. ### 명령 먼저 명령을 추가합니다. 명령은 이벤트를 발생시키는 트리거, 동작 또는 의도입니다. 파란색 포스트잇을 사용합니다. 명령은 현재 시제를 사용해야합니다. ![](https://hackmd.io/_uploads/rymLgc4Ph.png) ### 역할 이제 이벤트를 탐색하면서 관련된 주요 사람들에 대해 생각해 보십시오. 우리는 그것들을 역할이라고 부릅니다. 역할은 인간 또는 시스템이 될 수 있습니다. 노란색 스티커 메모를 사용하여 표시합니다. ![](https://hackmd.io/_uploads/BJnLxqNPn.png) 관련된 역할은 다음과 같습니다. - 고객 - 카운터 직원 - 바리스타 - 웨이터 명령은 내부/외부의 이벤트, 사람 또는 시스템에 의해 트리거 될 수 있습니다. ![](https://hackmd.io/_uploads/BktDe9Nvn.png) 사실 이 명령을 수행하여 이벤트를 발생시키는 무언가가 필요하다는 것을 깨달으신 분도 계실겁니다. 지금은 Command와 Event사이의 인터페이스 "?"라고 부르겠습니다. 이는 요청이 발생하면 내부적으로 처리하는 핵심요소이며 프로세스가 완료될때 다시 이벤트를 발행합니다. ### 예외 또는 위험한 이벤트 이벤트 탐색 여정 내내 벽에 붙여진 다양한 스티커 메모가 있습니다. 하지만 모든 이벤트가 순조롭게 진행되는 것은 아닙니다. 비용 효율적인 방법으로 이 작업을 수행하려면 가장 위험한 여정을 떠나야합니다. 바로 예외를 탐색하십시오. 여기에서 더 많은 이벤트를 찾고 여정을 확장하여 비즈니스 흐름을 풍부하게 할 수 있습니다. #### 위험한 이벤트를 처리하기 위한 솔루션 생각하기 빨간색 스티커 메모는 실패 시나리오를 나타냅니다. 예를 들어 커피숍 시나리오에서 비즈니스 흐름의 결과가 잘못됬을 경우를 가정합니다. 고객이 테이블 번호를 제공하지 않고 커피를 주문했다면 어떻게 될까요? 바리스타가 커피를 잘못만들었다면? ![](https://hackmd.io/_uploads/B1x2-qNwh.png) 실패든 실수든 관계없이 고객 경험에 영향을 미칩니다. 이러한 문제를 예방하거나 해결하기 위한 추가 조치를 선별하기 위해 이러한 문제에 대해 다시 생각할 필요가 있습니다. 필수적인 것은 아니지만 이 단계는 이전에 익숙하지 않은 비즈니스 시나리오를 처리하는 데 도움이 될 수 있습니다. 시나리오를 앞뒤로 계속 시뮬레이션하면서 질문,위험 또는 예외 중 일부를 삭제하며 정교한 스토리로 성장시켜보세요. # 어그리게이트(Aggregate) 지금까지 중심 요소 "(?)"가 비즈니스 기능을 제공하고 역할에서 명령을 수락하거나 거부할 책임이 있다는 것을 알고 계실 것입니다. 이를 **Aggregate(어그리게이트)** 라고 합니다. ![](https://hackmd.io/_uploads/rkcuGcNDh.png) 그러나 초기 단계에서는 참가자가 이벤트 및 명령의 수집에 집중하는 것을 권장합니다. 그 다음 이러한 개체 간의 관계를 구축하는 데 더 집중하십시오. :::warning Aggregate는 일반적으로 참가자가 개념을 이해하려고 하면 가장 큰 혼란을 야기합니다. 노란색 스티커를 붙이고 지금은 이름을 비워두고 물음표로 표시하십시오. 팀이 도메인을 완전히 이해할 때까지 이름 지정을 연기하십시오. ::: ### 네번째 라운드 - 재정렬 및 모델링 이제 타임라인을 떠나 포스트잇을 그룹화할 시간입니다. 이를 통해 다음과 같은 새로운 관계를 정의할 수 있습니다. ![](https://hackmd.io/_uploads/Bk8KAFTwh.png) - 어떤 사용자가 어떤 명령을 트리거합니까? - 어떤 명령이 어떤 집계 또는 외부 시스템에 영향을 미치고 어떤 변경을 트리거합니까? - 명령 처리 중에 어떤 어그리게이트 또는 외부 시스템이 어떤 이벤트를 트리거합니까? - 어떤 이벤트가 어떤 정책을 트리거합니까? - 어떤 이벤트가 어떤 사용 사례에 대해 어떤 읽기 모델을 생성합니까? - 어떤 정책이 어떤 새 명령을 호출합니까? ## Aggregate 네이밍 먼저 이름을 정해야합니다. Aggregate 네이밍 규칙의 몇 가지 예입니다. ![](https://hackmd.io/_uploads/ryV6WcNv3.png) - 명사별 - 동명사(명사 + ing) 어떤 규칙을 선호하든 어그리게이트가 "무슨기능을하는지"을 제시해야 합니다. 즉 어그리게이트가 수신한 각 명령을 통과하고 발생한 각 이벤트가 합리적인지 확인해야 합니다. :::spoiler 대략적인 결과물 ![](https://hackmd.io/_uploads/rJQJUjHwn.png) ::: :::spoiler 또 다른 예제 동일한 예제는 아니지만 이런식으로 여러분의 아키텍처를 비지니스 도메인으로 분리할 수 있습니다. https://miro.com/app/board/o9J_kt3rZb4=/?fromEmbed=1 ::: # 제한된 컨텍스트(Bounded Context) 형성 점점 더 많은 Aggregate가 캡처됨에 따라 어떤 Aggregate는 응집력이 있고 다른 Aggregate는 그렇지 않다는 것을 알 수 있습니다. 명확한 제한된 컨텍스트를 갖도록 경계를 형성하는 데 도움이 되는 간단한 패턴이 있습니다. - 명령 A가 실행되고 이벤트 A가 발생합니다. - 이벤트 A는 정보 A를 제공합니다. - Command B를 사용하는 조건을 수행하는 동안 View A도 필요합니다. - 이런 경우 명령 A와 명령 B는 하나의 모듈에 함께 있는 것이 좋을 수 있습니다. 이러한 응집력 있는 집합체를 함께 둘러싸면 자연스럽게 경계가 설정됩니다. ![](https://hackmd.io/_uploads/SJYZGqVP3.png) 제한된 컨텍스트 패턴은 유비쿼터스 언어의 일관성을 보호할 뿐만 아니라 모델링도 가능하게 합니다. 모델의 목적, 즉 경계를 지정하지 않고는 모델을 만들 수 없습니다. 경계는 언어의 책임을 나눕니다. 하나의 제한된 컨텍스트에 있는 언어는 특정 문제를 해결하기 위해 비즈니스 도메인을 모델링할 수 있습니다. 또 다른 제한된 컨텍스트는 동일한 비즈니스 엔터티를 나타내지만 다른 문제를 해결하기 위해 모델링할 수 있습니다. 또한 서로 다른 제한된 컨텍스트의 모델을 독립적으로 발전시키고 구현할 수 있습니다. 즉, 제한된 컨텍스트 자체는 독립적이지 않습니다. 독립적인 구성 요소로 시스템을 구축할 수 없는 것처럼 구성 요소는 시스템의 중요한 목표를 달성하기 위해 서로 상호 작용해야 하므로 제한된 컨텍스트에서 구현해야 합니다. 독립적으로 진화할 수 있지만 서로 통합해야 합니다. 결과적으로 제한된 컨텍스트 사이에는 항상 터치포인트가 있습니다. 이를 계약(contracts)이라고 합니다. - 파트너십(Partnership) ![](https://hackmd.io/_uploads/ryJlOqVvh.png) - 공유 커널(Shared kernel) ![](https://hackmd.io/_uploads/r1gbOcNP2.png) - 고객-공급자(Customer-Supplier Development) ![](https://hackmd.io/_uploads/Hkr7qc4wn.png) - 순응(Conformist) : 업스트림(서버) ![](https://hackmd.io/_uploads/SyQOqcNwn.png) - 부패 방지 계층(Anticorruption Layer) ![](https://hackmd.io/_uploads/HJ45scNwn.png) - 오픈 호스트 서비스(Open Host Service) ![](https://hackmd.io/_uploads/H1GGhcNP2.png) - 공개 언어(Published Language) ![](https://hackmd.io/_uploads/rygZhc4Pn.png) - 분리된 방법(Seprate Ways) ![](https://hackmd.io/_uploads/r1mX35EP3.png) 컨텍스트 맵은 시스템의 서로 다른 제한된 컨텍스트 간의 협업 또는 조직 팀의 관계를 반영할 수 있습니다. ![](https://hackmd.io/_uploads/S1NLRcNDh.png) 일부 종속성이 무엇인지, 업스트림(예: API 계약)이 변경될 때 영향 범위가 무엇인지, 유해한 다운스트림 영향을 방지하는 방법을 발견할 수 있는 "제한된 컨텍스트 매핑"을 수행하는 것은 가치가 있습니다. # 참조 ### AWS Samples : Event Storming -https://github.com/aws-samples/designing-cloud-native-microservices-on-aws/tree/main