[Architect] DDD(Domain Driven Design)

Mineru·2021년 12월 5일
0

최근 소프트웨어 설계에 대한 핵심 키워드라고 하면 DDD 또는 MSA라고 할 수 있을 것 같다.
자주 보는 페이스북 개발자들의 피드에도 수시로 올라오고 빅테크 기업들의 아키텍처라면서 소개가 되고 최근 투자 영역에서 '메타버스'라는 단어가 많이 나오는 만큼 개발 영역에 있어서는 'DDD'와 'MSA'가 아주 핫 한 것 같다.

첫번째 D, Domain이란?

사회라는 단위에서는 어떠한 분야나 영역. 학문에 있어서는 연구 분야가 될 수 있고, 회사라는 조직 단위에서는 일하는 분야가 곧 도메인이라고 볼 수 있다.

그럼 개발에 있어서는 도메인은 어떻게 묘사를 할 수 있을까?
어떠한 로직에 있어서의 동작들의 집합을 도메인이라고 할 수 있을 것 같다.

동작들의 집합이라고 하면, 쇼핑을 예시로 들어보겠다.

판매 상품 진열, 상품 주문, 배송, 배송 중계, 판매자 업무 관리 이렇게 업무를 크게 나눌 수 있을 것이고, 크게 나눈 업무에서 다시 하위로 단위로 기능이 부여가 될 것이다.

  • 판매 상품 진열 : 추천, 카테고리 분류화, 상품평 등
  • 상품 주문 : 결제, 회계 처리 등
  • 배송 : 상품 운송자 배치 전략 등
  • 배송 중계 : 주문 상품 위치 추적 등
  • 판매자 업무 관리 : 판매 상품 등록, 재고 관리, 구매자 정보 입력 등

DDD 전략적 설계

  1. 비즈니스 도메인의 상황(Context: 대상 사용자)에 맞게 설계하자는 컨셉
  2. 전략적 설계를 위해 비즈니스 도메인의 상황을 Event Storming으로 공유하고, 비즈니스 목적별로 서비스들을 그룹핑한다.
  3. Bounded Context & Domain Model
    • Bounded Context : 비즈니스 도메인의 사용자, 프로세스, 정책/규정 등을 고유한 비즈니스 목적별로 그룹핑한 것.
    • Domain Model : 비즈니스 도메인의 서비스를 추상화한 설계도.
  4. Bounded Context & Micro Service : 1개의 Bounced Context는 최소한 1개 이상의 Micro Service로 구성 됨.
  5. Context Map : Bounded Context 간의 관계를 나타낸 도식화한 Diagram.
  6. 유비쿼터스 언어
    • 현업 실무자, 개발자, 디자이너 등 참여자들이 동일한 의미로 이해하는 언어.
    • 비즈니스 도메인에 따라 동음이의어가 많기 때문에 정확한 커뮤니케이션을 위해 공통 언어를 정의하고 사용해야 함.
    • 하나의 도메인내에서는 어떤 단어나 문장이 동일한 의미로 소통된다. 예를 들어 '마우스'라는 단어는 '컴퓨터 부속품 생산' 도메인 안에서는 '컴퓨터 화면 안에서 커서를 옮기는 컴퓨터 부속품'으로 통용 된다. '해충 박멸 서비스' 도메인 안에서는 '꼬리 달리고 털이 나있는 짐승'으로 이해가 된다.

Domain Model

실제 세계를 반영하는 구체적인 설계로, 주택 건축시에 주택을 구성하는 메인 주택의 구체적인 설계도를 말한다.

  • Problem Space : 비즈니스 분할
    • Core Sub-Domain : 비즈니스 목적 달성을 위한 핵심 도메인으로 차별화를 위해 가장 많은 투자가 필요함
    • Supporting Sub-Domain : 핵심 도메인을 지원하는 도메인
    • Generic Subdomains : 공통 기능(메일, SSO 등) 도메인으로서 3rd Party 제품을 구매하는것이 효율적임
  • Solution Space : Context Map 정의
    • 관계의 종류
      • Shared Kernel: 복수의 Bounded Context가 공통으로 사용하는 Bounded Context간의 관계
      • Upstream-Downstream: Publisher(=Upstream)와 Subscriber(=Downstream) 관계
    • Bounded Context의 특성 종류
      • Open Host Service: 여러 종류의 Downstream Bounded Context를 고려하여 설계되는 Upstream Bounded Context
      • Anti Corruption Layer: 다른 Bounded Context에서 받는 데이터를 본인에 맞게 구조, Type, 통신프로토콜 등을 변환해 주는 모듈계층을 가지는 Bounded Context. 보통 Downstream Bounded Context가 ACL을 가짐.

Event storming

비즈니스 도메인 내에서 일어나는것들을 찾아 Bounded Context를 식별하는 방법론

  1. Domain Event 정의 : 비즈니스 도메인내에 발생하는 모든 이벤트를 과거형으로 기술 - "오렌지색"
    • 이벤트는 Actor가 Action을 해서 발생한 결과입니다. 보통 문장은 "XXX가 되었다."형태가 됩니다.
    • 각자 생각나는 Event를 적고 바로 순서없이 붙입니다. 더 이상 생각이 안 날때까지 붙입니다. 서로 상의하지 않습니다.
    • 서로 상이하면서 중복된것을 없애거나 합칩니다.
    • 이벤트가 발생하는 시간 순서대로 붙입니다. 동시 수행되는 이벤트는 수직으로 붙입니다.
    • 이슈/개선사항/관심/재논의 사항이 있으면 "빨간색" 포스트잇으로 이벤트 옆에 붙입니다.
    • 주의: 비즈니스 용어로 무슨 일이 발생했는지를 적는것이지, 시스템 내에서 발생되는것을 찾는게 아닙니다.
    • TIP: 왼쪽과 오른쪽에 공간 여유를 두고 붙이십시오.
  2. Tell the story : 도출된 이벤트로 도메인의 업무 흐름을 이해하고 토론하여 보완
    • 도메인 전문가가 도출된 이벤트를 갖고 업무 흐름을 설명합니다.
    • 상호 질문을 통해 도메인 이벤트를 추가하거나 조정합니다.
    • 이슈/개선사항/관심/재논의 사항이 있으면 "빨간색" 포스트잇으로 이벤트 옆에 붙입니다.
  3. 프로세스로 그룹핑 : 이벤트들을 프로세스로 그룹핑
    • 동일한 비즈니스 주제(업무 프로세스)로 이벤트들을 그룹핑합니다. "보라색" 포스트잇에 프로세스명과 간략설명을 기술합니다.
    • 비즈니스적으로 중요한 핵심 프로세스에 집중합니다. 핵심 프로세스에 중요한 이벤트가 누락되지 않았는지 검토합니다.
      지원 프로세스는 너무 자세하게 이벤트를 식별하지 않습니다.
    • 이슈/개선사항/관심/재논의 사항이 있으면 "빨간색" 포스트잇으로 이벤트 옆에 붙입니다.
  4. Command 정의: 각 Domain Event를 발생시키는 명령을 현재형으로 정의하며 명령형(ex: 제품목록을 검색)으로 기술 - "파란색"
    • 사용자의 행위가 Command가 됩니다. Command는 일반적으로 '무엇을 CRUD 요청한다." 또는 "무엇을 XX한다.'의 형태가 됩니다. (CURD란 Create Update Read Delete의 약자입니다.) 예) 자동이체계좌의 등록을 요청한다. 판매상품 목록의 조회를 요청한다. 고객의 이메일 변경을 요청한다. 관심상품을 선택한다.
    • 각 Event별로 그 Event를 발생시키는 Command가 무엇인지 생각하여 Event 왼쪽에 붙입니다. Command 하나에 1개 이상의 Event가 발생할 수 있습니다.
      ※ 추가적인 Event가 생각나면 추가할 수 있습니다.
  5. Trigger 정의: Command를 일으키는 Actor와 Event를 일으키는 External System와 Policy/Rule을 정의
    • Command를 수행하는 Actor를 정의합니다. Actor를 Command의 왼쪽 하단에 겹쳐서 붙입니다. - "하늘색"
      Actor는 사람이며, 구체적인 사용자 유형을 적는것이 좋습니다.
    • Event 발생과 관련된 외부 시스템이 있다면 Event의 우측 상단에 겹쳐서 붙입니다. - "초록색"
      Command의 요청을 받아 데이터만 제공해 주는 경우도 있고, 직접 무언가를 처리해서 결과를 리턴하는 외부시스템도 있습니다.
      또한, 외부 시스템은 Command 없이 Event를 발생시킬 수도 있습니다.(예: '푸시알림이 도착했다.'라는 이벤트는 '카카오톡' 같은 외부시스템이 Command 없이 발생시키는 이벤트입니다.) 외부시스템이란 현재 시스템 밖에 있는 시스템을 의미합니다. 회사 내 시스템일 수도 있고, 회사 외부에 있는 시스템일 수도 있습니다.
    • 이벤트와 관련된 정책이나 규정이 있으면 Event 우측 하단에 붙입니다. - "보라색"
      그 이벤트가 발생하기 위해 사전 체크할 정책/규정(예: 이름, 이메일은 필수 정보)이나 이벤트 발생 시에 정책/규정(예: 주민번호 뒷자리는 마스킹 처리)을 적습니다.
      또한, 정책(Policy)이나 규정(Rule)은 Event를 발생시킬 수 있습니다. 보통 이러한 정책/규정은 시간과 관계가 있습니다.
      예를 들어 "매월 말일에 1개월 내 만기가 도래하는 고객 리스트를 전 영업직원에게 메일로 통보한다."라는 Rule이 있다면 이 Rule도 "1개월 내 만기 도래 고객 리스트가 통보되었다"라는 이벤트를 일으키는 Trigger가 됩니다.
  6. Aggregate 정의: Command 수행을 위해 CRUD해야 하는 데이터 객체 정의 - "노란색"
    Aggregate는 아래와 같이 Entity와 VO의 집합입니다. 하지만 Event storming때 이렇게까지 도출하는것은 어려울 경우가 많습니다.

따라서, 이 단계에서는 Entity까지만 정의하고 다음 단계인 Bounded Context단계로 진행할것을 추천합니다.

  1. Bounded Context정의 - "분홍색"
    - Entity, command, event, actor, Policy/Rule을 보면서 어떤 주제와 관련되었는지를 논의 합니다.
    • 바운디드컨텍스트는 사용자, 프로세스, 정책/규정 등을 고유한 비즈니스 목적별로 그룹핑한것입니다.
      Entity, command, event, actor, Policy/Rule을 보면서 어떤 주제와 관련되었는지를 논의 합니다. 프로세스 그룹핑한것도 참조합니다.
  • 그 주제별로 경계를 선으로 구분합니다. 처음에는 흐린색 펜으로 그리고 확정되면 검은색 마커팬으로 그립니다.
  • 그 주제명, 즉 Bounded Context의 명칭을 "분홍색" 포스트잇에 적어 붙입니다.
  1. Context Map 작성 : Bounded Context간의 관계를 도식화합니다.
  • 관계의 종류
    • Shared Kernel: 복수의 Bounded Context가 공통으로 사용하는 Bounded Context간의 관계
    • Upstream-Downstream: Publisher(=Upstream)와 Subscriber(=Downstream) 관계
  • Bounded Context의 특성 종류
    • Open Host Service: 여러 종류의 Downstream Bounded Context를 고려하여 설계되는 Upstream Bounded Context
    • Anti Corruption Layer: 다른 Bounded Context에서 받는 데이터를 본인에 맞게 구조, Type, 통신프로토콜 등을 변환해 주는 모듈 계층을 가지는 Bounded Context

Tatical Design

Strategic Design에서 설계한 각 Sub Domain별 Domain Model(Context Map)을 중심으로 설계하는것을 말한다.
1. 개발을 위한 구체적인 설계도입니다.
2. Model Driven Design
3. Layered Architecture

  • Tatical Design시 목적별 계층으로 나누어 설계하는것을 의미합니다.
  • 추천하는 Layer는 Presentation, Service, Domain, Data Layer가 있습니다.

아래는 Martin Fowler가 얘기하는 Layer구조입니다.

출처

https://steemit.com/kr/@frontalnh/domain-driven-design
https://happycloud-lee.tistory.com/94

profile
Daily Coding

0개의 댓글