- DDD(Domain Driven Design)
- DDD란?
- 도메인 모델
- DDD의 구조와 용어
- MSA에서의 DDD
DDD(Domain Driven Design)는 도메인 주도 설계를 뜻한다.
소프트웨어를 설계할 때 요구사항을 잘못 이해해 필요없는 기능이 만들어지는 등 수정하는 데 많은 시간과 노력이 들어갈 수 있다.
과거에는 기술 중심의 개발 방법론이 사용되어 비즈니스 전문가와 개발자 간의 소통이 원활하지 않으면 비즈니스 측면에서 발생하는 다양한 요구사항을 효과적으로 반영하기에는 한계가 있었다.
이러한 문제점을 해결하기 위해 DDD가 등장하게 되었다.
도메인이란 소프트웨어로 해결하려는 문제의 영역을 의미한다.(회원, 상품, 주문 등)
하나의 도메인 내부에는 하위 도메인이 존재할 수 있다. (회원 프로필, 상품 상세, 주문 상품 등)
도메인 모델은 도메인 주도 설계(DDD)에서 핵심 개념을 표현하는 방법이다. 이는 특정 도메인에 대한 지식, 규칙, 그리고 로직을 추상화하여 개념적으로 표현한 것이다.
예를 들어, 전자상거래 시스템에서 도메인 모델은 주문, 결제, 배송 같은 개념과 그들 간의 관계를 표현할 수 있다.
도메인 모델을 만들기 위해서는 핵심 구성 요소, 규칙, 기능을 파악해야 한다. 서비스의 요구사항을 분석하고 관련 기능들을 묶으면, 아래와 같은 구조를 만들 수 있다. 이런 도메인 모델의 집합을 바운디드 컨텍스트(Bounded Context)라고 한다.

도메인 모델은 크게 Entity와 Value로 나눌 수 있다.
엔티티(Entity)는 고유의 식별자를 갖는 객체로 자신의 라이프 사이클을 갖는다. 주문(Order), 회원(Member), 상품(Product)과 같이 도메인의 고유한 개념을 표현한다. 엔티티는 단순히 데이터를 담고 있는 데이터 구조가 아닌 데이터와 함께 기능을 제공하는 객체입니다. 도메인 관점에서 기능을 구현하고 기능 구현을 캡슐화해서 데이터가 임의로 변경되는 것을 막을 수 있다.
벨류(Value)는 고유의 식별자를 갖지 않는 객체로 주로 개념적으로 하나인 값을 표현할 때 사용된다. 배송지 주소를 표현하기 위한 주소(Address)나 구매 금액을 위한 금액(Money)와 같은 타입이 Value 타입이다.
Value는 엔티티의 속성 또는 다른 Value의 속성으로 사용할 수도 있다.
식별자는 시퀀스, DB의 자동 증가 컬럼, UID, 특정 규칙에 의한 고유한 값 등 다양한 방법으로 생성할 수 있다.
도메인 서비스는 특정 엔티티에 속하지 않는 도메인 로직을 담당한다.
예를 들어, "할인 금액 계산"은 상품, 쿠폰, 회원 등급, 구매 금액 등 다양한 조건을 고려하여 이루어진다. 이처럼 여러 엔티티와 값이 필요한 도메인 로직은 도메인 서비스에서 구현할 수 있다.

이러한 도메인 모델을 구성했을 때, 어떤 도메인 모델이 어떤 역할을 하는지 쉽게 판단하기 어렵다. 개별 객체 단위에서 상위 객체의 개념을 파악하려면 시간이 오래 걸리기 때문이다. 이것은 곧 코드 변경과 확장이 어려워짐을 의미한다.
따라서 이를 위해 관련된 객체들을 모아 하나의 단위로 취급하는 개념인 애그리거트(Aggregate)가 있다. 연관 도메인을 하나의 애그리거트로 묶으면 상위 수준에서 도메인 모델 간 관계를 쉽게 파악할 수 있다.
애그리거트에 속한 모든 객체의 일관성을 유지하려면 애그리거트를 관리할 주체가 필요하다.
이를 위해 애그리거트는 특정 도메인 군집에 속한 객체들을 관리하는 루트 엔티티를 갖는다.
하나의 애그리거트에는 반드시 하나의 루트 엔티티가 있으며, 여러 개의 엔티티와 밸류 객체들이 포함될 수 있다.
애그리거트를 사용하는 코드는 애그리거트가 제공하는 기능을 실행하며, 루트 애그리거트를 통해 간접적으로 애그리거트 내의 다른 엔티티나 밸류 객체에 접근할 수 있다. 이 방식은 애그리거트의 내부 구현을 숨겨서, 애그리거트 단위로 캡슐화할 수 있도록 돕는다.

이 예시 코드는 루트 애그리거트의 메서드를 통해 간접적으로 OrderProduct(하위 엔티티)에 접근하고 있다. 이를 통해 하위 엔티티들은 루트 엔티티의 라이프사이클을 따르게 된다.
DDD도 Layered Architecture 와 같이 표현,응용,도메인,인프라스트럭처 4개의 계층으로 이루어져 있으며 고수준 모듈이 저수준 모듈에 의존하지 않는 구조로 개발해야 한다. 만약 불가피하게 응용 계층에서 인프라스트럭처의 코드를 사용 할 경우 의존역전원칙(DIP) 을 이용하여 하위 계층에 의존하지 않는 형태로 개발해야 한다.

DDD는 특히 MSA에서 부각되었는데, 모놀리식 애플리케이션을 MSA로 전환하는 과정에서 서비스를 식별하고 분석 및 설계하는 데 DDD가 큰 도움을 주기 때문이다.
복잡한 비즈니스 로직이나 모놀리식 애플리케이션을 MSA로 전환할 때, 가장 중요한 것은 서비스의 경계를 명확히 나누는 것이다. 예를 들어, 모놀리식 이커머스 플랫폼을 MSA로 전환할 때는 주문, 상품, 리뷰와 같은 도메인 개념을 기준으로 마이크로서비스를 구축하게 된다.
DDD는 도메인 모델을 중심으로 비즈니스 로직을 정의하고, 이를 독립적인 도메인 경계로 나눕니다. 따라서 MSA와 DDD를 함께 사용하면, 도메인 경계를 기반으로 각 도메인에 해당하는 마이크로서비스를 정의할 수 있다. 이렇게 하면 각 마이크로서비스는 단일 책임 원칙을 따르고, 특정 비즈니스 기능에 집중할 수 있게 된다.
