TIL

43일차 마이크로 서비스

김영재0412 2022. 6. 16. 21:51

도메인 주도 설계와 모놀리식 분해 전략

 

도메인

도메인은 소프트웨어로 해결하려하는 문제의 영역을 뜻하며 지식, 영향력 또는 활동 영역의 의미도 가지며 도메인 지식이라는 어떤 산업 또는 분야를 이해하기 위해 필요한 지식을 의미하기도 한다.

 

예를 들어 고객이 원하는 상품을 어떻게 잘 제공할 것인가? 의 대한 문제는 커머스라는 도메인이 있다. 커머스 도메인의 하위 도메인으로 판매자가 무엇을 판매할 것인가? 의 대한 문제는 상품이라는 도메인이 있으며 공통된 상품에 대해서 어떻게 공통 정보를 제공할 것인가? 의 대한 문제는 카탈로그 도메인이 있다.

 

그 밖에 판매자, 사용자, 카테고리, 주문, 배송 등 많은 도메인이 존재합니다.

 

도메인 주도 설계(Domain Driven Design)란?

하나의 도메인 모델에 대한 이해관계가 각자 다름을 인정하고 각 팀에 적합한 하위 도메인을 설정하고 해당 하위 도메인에 대한 맥락을 알고 있는 사람이 따라야 할 비지니스 규칙에 대한 경계를 설정하는 설계 방식이다.

 

즉, 도메인 내부에서 문제 해결이 가능한 형태로 도메인을 모델링 하는 기법이며 마이크로 서비스와 궁합이 좋다. 

 

도메인 주도 설계는 크게 전략적 설계와 전술적 설계로 나뉜다.

 

전략적 설계

도메인 전문가 및 기술팀이 함께 모여 유비쿼터스 언어를 통해 도메인 지식을 공유 및 이해하고 이를 기준으로 개념과 경계를 식별해 바운디드 컨텍스트(bounded context)로 정의하고 경계의 관계를 컨텍스트 맵(context map)으로  정의하는 활동이다.

 

전술적 설계

전략적 설계에서 도출된 바운디드 컨텍스트와 도메인을 이용하여 애그리거트 패턴, 엔티티와 값 객체, 레포지토리, 등을 구성하고 구현하는 활동이다.

 

보편 언어(Ubiquitous Language)

 

 

 

 

 

 

 

도메인의 특정 업무와 관련된 사람들 사이에 통용되는 개념이다.

 

예를 들어, 유럽에서 커피는 물을 타지 않은 에스프레소를 의미하고 미국에서의 커피는 아메리카노를 의미하기에 서로 같은 단어를 다른 의미로 받아드릴 수 있다.

 

모든 팀원이 특정 용어를 들었을 때 같은 것을 생각할 수 있는 명확하게 정의된 언어가 필요하며 용어에 각자 다른 생각을 하거나 같은 것을 말하지만 용어가 다른 경우가 있으면 안된다.

도메인에서 사용하는 언어는 코드에 그대로 똑같이 반영되야하며 똑같이 반영되지 않으면 개발자는 해당 용어를 해석하고 이해해야하는 부담이 생긴다.

 

한정된 맥락(Bounded Context)

도메인의 영역의 경계이며 도메인 모델은 특정한 컨텍스트 안에서 완전한 의미를 갖는다.

 

고객이라는 도메인은 결제 도메인 입장에서는 신용카드 정보나 계좌 정보를 가진 결제자로서 사용되고 배송 도메인 입장에서는 상품을 받을 주소와 우편번호, 전화번호를 소유한 수취자를 의미한다.

 

바운디드 컨텍스트는 여러개의 서브 도메인으로 구성되고 하나의 서브 도메인은 한 바운디드 컨텍스트에 포함된다.

 

 위 그림과 같이 결제, 배송 컨텍스트에는 하나의  팀에만 활당되어야 좋은 바운디드 컨텍스트라 할 수 있으며, 하나의 팀은 여러 개의 바운디드 컨텍스트를 가질 수 있다. 또한 각각의 바운디드 컨텍스트는 각각의 개별 환경을 가질 수 있다.

 

 

도메인 주도 설계의 주요 용어

  1. 도메인 이벤트: 발생한 사건
  2. 커맨드: 도메인 이벤트를 트리거하는 명령
  3. 외부 시스템: 도메인 이벤트가 호출하거나 관계가 있는 레거시 또는 외부 시스템
  4. 액터: 개인 또는 조직의 역할
  5. 핫스팟: 의문사항, 결정하기 힘든 사항
  6. 애그리거트: 도메인 이벤트와 커맨드가 처리하는 데이터, 상태가 변경되는 데이터
  7. 정책: 이벤트 조건에 따라 진행되는 결정, “이벤트”가 발생할 때, “커맨드”를 실행한다
  8. 정보: 액터에게 제공되는 데이터, 결정을 내리는데 영향을 주는 정보

 

도메인 주도 설계 실습 

 

1.  도메인 이벤트를 생각나는대로 적는다.

 

과거형 or 명사형으로 적어야하며 비즈니스 흐름에서 발생한 이벤트에 초첨을 맞춰서 결정한다.

자유로운 의견을 통해 도출된 도메인 이벤트들을 발생 순서를 고려하여 배치한다. 시간 순서는 왼쪽에서 오른쪽으로 흘러간다.

 

 

2. 외부 시스템을 필요로하는 프로세스를 찾아서 도메인 이벤트 뒤에 붙인다.

 

명사형으로 적어야 하며 카드 시스템, 문자 시스템 같은 것들이 있다.

 

 

3. 커맨드를 도메인 이벤트 앞에 배치한다.

 

하나의 커맨드에 여러개의 이벤트가 발생할 수 있으며 개발자 입장에선 구현해야할 API가 된다.

 

 

4. 핫스팟을 찾아서 배치한다.

 

궁금한사항이나, 좀 더 논의가 필요한 사항, 결정하기 힘든 사항에 대한 내용을 붙인다.

 

 

5. 액터를 찾아서 배치합니다.

 

액터는 사용자의 역할을 말하며 비즈니스를 수행하는 구체적인 역할을 고려해서 도출하도록 한다.

해당 쇼핑몰 사례에서는 사용자를 게스트, 회원, 판매자, 구매자 등으로 구분할 수 있습니다.

 

 

6. 문장으로 액터, 커맨드, 이벤트를 검토해본다.

 

{구매자:액터}가 상품 {주문을 취소:커맨드}하면 {상품주문취소됨:도메인이벤트} 이벤트가 발생하고, 주문 취소된 상품의 재고를 변경하는 {상품재고수정:커맨드}이 실행되어서 {상품재고수정됨:도메인이벤트} 이벤트가 발생함으로써 시스템이 동작한다" 처럼 검토 해본다.

 

 

7. 애그리거트를 정의합니다.

 

애그리거트는 가장 작은 도메인 모델의 모듈 단위이며 커맨드와 도메인 이벤트가 영향을 주는 데이터 요소이다. 개발자의 입장에서 보면, 도메인의 실체 개념을 표현하는 객체(엔티티)로 구현하게 될 대상이다. 커맨드와 도메인 이벤트 사이 상단에 겹쳐서 붙입니다.

 

 

 

8. 바운디드 컨텍스트를 정의하고 정책을 도출합니다

 

도메인이벤트와 커맨드, 액터, 애그리거트를 고려해서 경계를 식별합니다.

애그리거트의 이름으로 컨택스트 이름을 정의합니다. 이 과정에서 동일 애그리거트 중심으로 모듈화가 이루어집니다.

정책을 도출해서 붙이며 정책은 이벤트 뒤에 따라오는 반응적인 비즈니스 로직입니다.

어딘가의 커맨드를 작동시키는 역할을 하기 때문에 도메인 이벤트와 커맨드 사이에 존재하게 됩니다.

 

 

 

9. 호출 관계의 방향성을 고려하여 컨택스트 매핑을 진행합니다.

 

  • 바운디드 컨텍스트 간의 관계를 파악합니다
  • 동기적 호출방식과 비동기적 호출방식을 고려한 표현도 가능합니다.
  • 동기적(실선) : 항상 일관된 데이터 필요, 컨텍스트간 의존도가 높음
  • 비동기적(점선) : 결과적 일관성으로 처리가능한 관계 ex)
  • 클라이언트 -> 구매 컨텍스트 (동기적) -> 고객이 상품을 주문 : 즉시 수행되어야함
  • 클라이언트 -> 상품 컨텍스트 (동기적) -> 고객이 상품정보를 조회 : 즉시 수행되어야함
  • 구매컨텍스트 -> 배송 컨텍스트 (비동기) -> 배송 컨텍스트에 장애가 발생해도 주문을 받아둠, 배송 시스템 정상화 시 주문-배송 연결 -> 고가용성을 보장

 

 

위를 바탕으로 만든 도메인 주도 설계이다.

'TIL' 카테고리의 다른 글

45일차 마이크로서비스  (0) 2022.06.20
44일차 마이크로서비스  (0) 2022.06.17
42일차 마이크로서비스  (0) 2022.06.15
36일차 배포 자동화  (0) 2022.06.07
35일차 배포 자동화  (0) 2022.06.03