
개발 공부를 한지 벌써 1년하고 3개월이 지났다.
여지껏 개발하면서 사용되는 기술에 대해 많이 공부하고,
React를 효율적으로 사용하는 것에 대한 고민을 많이했다.
이제 컴퓨터로 조금은 말을 할 줄 알기 시작했으니,
문단이나 글을 쓰는 법에 관해 필요성을 느꼈다.
운이 좋게도, 과제를 통해 개발자 분과 소통했는데 그 과정에 내가 부족한 부분들이
무엇인지 바라 볼 수 있었고, 필요한 부분들을 하나하나 채워갈 예정이다.
더 좋은 개발자로 성장하겠다.
성능, 생산성, 안정성이 뛰어난 애플리케이션을 만들기 위해서는 설계를 잘하는 것이 중요하다.
이러한 설계를 편리하게 하기 위해서 구성한 방법이 DDD(Domain-Driven Design) 도메인 주도 설계이다.
DDD를 알기 위해서는 먼저 Domain에 대해 알아야한다.
도메인이란 사전적 의미로 '영역', '집합' 이다.
애플리케이션 개발에서 사용하는 도메인이라는 단어는 비즈니스적인 업무 영역과 관련이 있다.
도메인을 쉽게 이해하기 위해 음식 주문 애플리케이션을 만든다고 가정한다.
음식 주문 배달 애플리케이션의 도메인은
음식을 주문하는 고객,
주문받은 음식을 만들고 판매하는 음식점,
완성된 음식을 배달하는 배달원,
해당 음식을 주문하고 결제하는데 이용되는 카드사 또는 은행
이 필요하다.
이들을 각각의 도메인이라 부를 수 있다.
기존의 어플리케이션 설계는 비즈니스 도메인에 대한 이해가 부족한 상태에서 설계 및 개발했다는
반성에서 시작하였다.
그래서 비즈니스를 도메인 별로 나누어 설계를 하여 확장성을 고려하고 모듈간의 의존성은 최
소화하고 응집성은 최대화 했다.

도메인 주도 설계의 목적은 소프트웨어의 복잡성을 최소화 하는 것이고,
더불어 구분이 명확하게 되어있기 때문에 요구사항을 쉽게 반영하고 소통이 원활하게 이루어질 수 있다.
많이 사용하는 데이터 중심의 접근법을 탈피하고, 도메인 모델과 로직에 집중한다.
분석 모델과 설계가 일치한다. 도메인 모델부터 코드까지 항상 함께 움직이는 구조의 모델을 지향한다.
전략적 설계에서 비즈니스 전문가와 개발자가 비즈니스를 개념화하기 위해 사용하는 언어.

도메인에서 사용하는 용어를 코드에 반영하지 않으면 그 코드는 개발자에게 코드의 의미를 해석해야 하는 부담을 준다.
이를 통해 코드를 분석하고 이해하는 시간을 절약하고, 용어를 정의 할 때마다 사전에 이를 기록하여 다른 사람들도 공통 언어를 사용할 수 있도록 한다.
그러면 어플리케이션 모델을 발전시키고 새롭게 생기는 도메인 관련 이슈를 해결하기 위해 도메인 전문가와 끊임없이 협력할 수 있게 된다.
도메인을 우선으로 설계하고 이를 바탕으로 개발해야한다.

먼저 8가지의 도메인 설계의 주요 용어를 알아야한다.
도메인 이벤트는 시간 흐름에 따른 시스템 동작을 의미한다.
외부 시스템은 도메인 이벤트를 호출하거나 관계가 있는 레거시 또는 외부 시스템을 의미한다.
커맨드는 도메인 이벤트를 트리거하는 명령이다.
핫스팟은 의문사항, 결정하기 힘든 사항을 말한다.
액터는 사용자 역할을 말한다.
애그리거트는 도메인 이벤트와 커맨드가 처리하는 데이터, 상태가 변경되는 데이터
정책은 이벤트 조건에 맞추어 발생하는 결정이다.
정보 액터에게 제공되는 데이터, 결정을 내리는데 영향을 주는 정보
쇼핑몰을 주제로 한 DDD 실습 예제 보기
고객이 회원가입을 해서 물건을 결제, 배송까지 Domain-Driven-Design으로 만드는 과정을 살펴보자
1. 도메인 이벤트 작성
도메인 이벤트는 시간 흐름에 따른 시스템 동작을 의미한다.
상태의 생성 / 변경 / 삭제가 발생하게 만든다.
비즈니스 흐름에서 발생한 이벤트에 초점을 맞추어 결정한다.
과거 시제 또는 명사형으로 기록한다.
이벤트들의 발생 순서를 고려하여 배치한다.
주황색으로 작성하였다.

다음과 같이 도메인 이벤트를 작성하였다. 소비자가 회원가입 후, 물건을 검색하면 장바구니에 추가하고 장바구니 안에 있는 물건을 구매해서 배송까지 과정이다.
2. 외부 시스템이 필요한 프로세스 추가
외부 시스템은 도메인 이벤트를 호출하거나 관계가 있는 레거시 또는 외부 시스템을 의미한다.
이제 그림에 필요한 프로세스를 추가한다.
명사형으로 작성한다.
아이템을 주문하였을 때, 결제하는 과정은 외부 결제시스템을 이용한다.
결제 승인을 할 경우, 외부 이메일시스템을 통해 결과를 전송한다.
핑크색으로 작성하였다.

결제 시스템과 이메일 시스템, 택배 배송 시스템을 추가하였다.
3. 커맨드 작성
커맨드는 도메인 이벤트를 트리거하는 명령이다.
하나의 커맨드에 여러 이벤트가 발생할 수 있다.
개발자 입장에서 구현하는 API이다.
청록색으로 작성하였다.

4. 핫스팟 배치
핫스팟은 의문사항, 결정하기 힘든 사항을 말한다.
궁금한사항이나, 좀 더 논의가 필요한 사항, 결정하기 힘든 사항에 대한 내용을 붙인다.
보라색으로 작성하였다.

5. 액터 찾아서 배치
액터는 사용자 역할을 말한다.
비즈니스를 이용하는 대상을 말한다.
쇼핑몰에서는 게스트, 회원, 판매자, 구매자 등으로 구분할 수 있다.
노란색으로 작성하였다.

이렇게 판매자와 구매자를 추가하였다.
문장으로 검증할 수 있는데,
구매자(액터)가 상품 결제를 클릭(커맨드}하면 장바구니 물건 결제(도메인이벤트)이벤트가 발생하고 외부 결제 시스템(외부시스템)으로 이어진다.
6. 애그리거트 정의
애그리거트는 도메인 이벤트와 커맨드가 처리하는 데이터, 상태가 변경되는 데이터
커맨드와 도메인 이벤트가 영향을 주는 데이터 요소이다.
개발자 입장에서 도메인의 실체 개념을 표현하는 객체(엔티티)로 구현할 대상이다.
커맨드와 도메인 이벤트 사이 상단에 겹쳐서 붙인다.
머스타드 색으로 작성하였다.

애그리거트에 대해 좀 더 자세히 설명하자면,

위와 같은 4개의 애그리거트가 있다면 애그리거트 루트(Aggregate Root)라는 것도 존재한다.
위에서 정의한 애그리거트 안에는 1개 이상의 도메인들이 있는데, 대표하는 도메인이 존재한다.
이를 애그리거트 루트라고 한다.
또한 특정 도메인이 다른 모든 도메인과 연관이 있다면 루트로 선정할 수 있다.
다시 본론으로 돌아와 이어서 남은 2개를 설명하겠다.
7. 바운디드 컨텍스트를 정의하고 정책 도출
정책은 이벤트 조건에 맞추어 발생하는 결정이다.
이벤트가 발생할 때, 커맨드를 실행한다.
도메인이벤트와 커맨드, 액터, 애그리거트를 고려해서 경계를 식별한다.
애그리거트의 이름으로 컨택스트 이름을 정의한다. 이 과정에서 동일 애그리거트 중심으로 모듈화가 이루어진다.
정책을 도출해서 붙인다.
정책은 이벤트 뒤에 따라오는 반응적인 비즈니스 로직이다.
어딘가의 커맨드를 작동시키는 역할을 하기 때문에 도메인 이벤트와 커맨드 사이에 존재하게 된다.
아래 그림에는 바운디드 컨텍스트를 정의하고 정책 도출하였다.
바운디드 컨텍스트(Bounded Context)는 도메인 주도 설계(DDD)에서 중요한 개념 중 하나로, 모델링한 도메인이 적용되는 경계를 명확히 정의하는 것을 말합니다. 간단하게 말하면, 특정 모델이 유효한 컨텍스트(즉, 경계 내)를 설정하는 것입니다.
정책은 연두색으로 작성하였다.

8. 호출 관계의 방향성을 고려하여 컨택스트 매핑
바운디드 컨택스트 간의 관계를 파악
동기적 호출방식과 비동기적 호출방식을 고려한 표현도 가능
동기적(실선): 항상 일관된 데이터필요, 컨텍스트간 의존도가 높음
비동기적(점선): 결과적 일관성으로 처리가능한 관계


DDD를 이용하여 설계를 하면 액터, 도메인에 따라 설계가 가능하고 마이크로서비스를 위한 설계가 가능하다.
지금까지 프로젝트를 만들어본 경험을 되짚어보니, DDD를 이용한 설계는 확실히 효과적이다.
이번에 과제하면서 폴더 구조에 대한 고민이 많았는데 DDD를 이용하여서 설계한다면,
의사결정이 더 쉬워질 것 같고, 주의 사항들 또한 관리하기 좋을 것이다.
다음 프로젝트에 적용해서 생산성을 높여보겠다.
출처 : https://ittrue.tistory.com/252
https://velog.io/@dnflekf2748/DDDDomain-Driven-Design
https://huisam.tistory.com/entry/DDD
https://velog.io/@pjh1011409/DDD-%EB%9E%80#%EF%B8%8F--ddd%EB%9E%80