DDD - 도메인 주도 설계

한라산·2024년 8월 25일

DDD

목록 보기
1/1
post-thumbnail

이 글은 이번에 DDD를 살짝 찍먹해 본 나의 생각을 정리한 글이다.

Domain-Driven Design

나는 이전까지 DDD == 도메인주도개발이라고 알고 있었다.
하지만 DDD도메인주도개발이 아닌 도메인주도설계이다.

도메인 주도 설계소프트웨어로 해결하고자 하는 도메인(문제 영역)을 중심으로 설계를 진행하는 설계 기법이다.

DDD는 크게 전략적 설계전술적 설계로 구분할 수 있다.

  • 전략적 설계 (Strategic Design)
  • 전술적 설계 (Tactical Design)
    • 도메인 주도 개발이라는 말은 전술적 설계를 진행하는 방법론이라고 생각한다.

전략적(Strategic)설계

비즈니스에서 소프트웨어로 해결하고자 하는 영역을 효과적으로 이해하고 모델링하는 단계

문제 영역(Problem domain) 식별

해결하고자 하는 도메인문제 영역이라고 한다.

도메인 예시

만약 모든걸 아날로그로 처리하던 영화관에서 예매를 소프트웨어로 처리하고 싶다는 요청이 들어왔다고 가정해보자
- 예매에는 상영 중인 영화 정보가 필요하다.
- 상영 중인 영화 정보예매를 진행한다.
위 내용을 정리하면 다음과 같이 두 가지 문제 도메인으로 나눌 수 있다.
- 상영 중인 영화 정보를 보여주는 영화 도메인
- 영화의 정보로 예매를 하는 예매 도메인

지식 탐구 (Knowledge Crunching)

프로젝트 전반에 걸쳐 도메인 전문가와 개발자가 모여 지속적으로 지식 탐구를 진행하여 도메인에 대해 더 깊이있게 이해해야 한다.

지식 탐구란

도메인 전문가와 개발자 같은 주요이해관계자가 모여 도메인에 대해 탐구하는 과정이다.
이 과정을 통해 유비쿼터스 언어정의하거나 숨겨진 도메인의 규칙을 찾아내는 등
도메인에 대해 더 깊이 이해하는 과정을 말한다.
이 과정은 지속적이고 반복적으로 이루어져야 한다.

하위 도메인 식별

문제 도메인을 추출했다면 이 도메인을 하위 도메인으로 식별할 수 있다.

위 도메인 예시로 보면 예매 도메인영화 도메인이 될 수 있다.

하위 도메인 유형 분류

식별된 하위 도메인에 다음과 같은 유형으로 분류할 수 있다.

  • 핵심 도메인 - 비즈니스의 핵심 경쟁력을 제공하는 영역
  • 지원 도메인 - 핵심 도메인을 지원하는 중요한 영역이지만 차별화 요소는 아님
  • 일반 도메인 - 비즈니스에 필요하지만 특별한 맞춤화가 필요 없는 영역

유형을 나누는 이유는 조직의 리소스를 적재적소에 배분해야 하기 때문이다.

바운디드 컨텍스트 정의

각 하위 도메인에 대한 경계를 바운디드 컨텍스트로 정의한다.
지식 탐구에서 정의한 유비쿼터스 언어바운디드 컨텍스트 단위로 고유해야 한다.

바운디드 컨텍스트란

복잡한 도메인을 관리 가능하게 정의한 단위

바운디드 컨텍스트 맵 작성

바운디드 컨텍스트 간의 관계를 시각화하여 이해관계자간의 커뮤니케이션을 원활하게 한다.

이때 컨텍스트간의 관계를 상류(Upstream)하류(Downstream)라는 개념으로 의존성을 나타낸다.

  • 상류(Upstream)
    • 데이터를 제공하는 영역
    • 변경이 데이터를 제공받는 쪽에 영향을 줌
  • 하류(Downstream)
    • 데이터를 제공받는 영역
    • 상류의 변경에 대응해야함

전술적(Tactical)설계

전략적 설계에서 정의된 바운디드 컨텍스트 내부의 세부적인 구현 방법을 다루는 단계

도메인 모델을 구체화하고, 실제 코드를 구현하여 비즈니스 로직을 명확하게 표현한다.

정의된 내용을 우선 개념모델로 만들고 구현모델로 변환하는 과정을 거친다.
처음부터 완벽한 모델을 만들기보다는 전체적인 윤곽을 개념모델로 만들고 구현과정에서 점진적으로 발전시키는게 좋을것 같다.

도메인 지식이라는게 한번에 완성될 수도 있겠지만 보통은 프로젝트가 진행되면서
도메인 지식이 쌓이고 그로인해 통찰력이 높아질거라 생각한다.
그렇기 때문에 처음에는 적합했던 모델이 현재의 도메인지식을 가지고 봤을 때는 적합하지 않을 수 있기 때문이다.

도메인 모델 정의

객체마다 고유한 식별자가 있는 도메인 모델을 정의한다.

특징으로는

  • 무의미한 public setter를 사용하지 않는다.
    • 의도하지 않은 상태의 변경을 막는다.
  • 비즈니스 기능을 모델 내부에 구현한다.

벨류타입(값객체) 식별

흔히 벨류타입이라고도 한다.

여러 개의 속성이 하나의 개념으로 표현할 때 벨류타입이 유용하게 사용된다.
예) 나라,도시,지번 같은 필드는 주소 라는 타입으로 묶을 수 있다. 이 때 주소벨류타입이다.

특징으로는

  • 값객체는 불변이다.
  • 값객체의 속성이 변경된다면 객체를 새로 생성한다.

애그리거트

관련된 도메인을 하나의 단위로 묶어 일관성을 유지한다.

바운디드 컨텍스트도 단위를 묶어주는게 아닌가??

바운디드 컨텍스트는 서로 다른 도메인간의 경계를 정의하고
애그리거트는 관련 객체들을 묶어 일관성을 유지하는게 목적이다.

특징으로는

  • 애그리거트에 속한 객체는 유사하거나 동일한 라이프 사이클을 갖는다.
  • 애그리거트 자신을 관리하고 다른 애그리거트는 관리하지 않는다.
  • 애그리거트 루트라는 애그리거트를 관리하는 객체를 지정해서 이곳에서만 상태의 관리를 한다.

도메인 서비스 정의

특정 엔티티나 값 객체에 속하지 않는 도메인 로직을 처리한다.

주로 다음 상황에서 사용한다.

  • 계산로직 - 여러 애그리거트가 필요한 계산 로직, 한 애그리거트에 넣기 다소 복잡한 로직
  • 외부 시스템 연동이 필요한 도메인 로직 - 구현하기 위해 타 시스템을 사용해야 하는 도메인 로직

특징으로는

  • 도메인 로직 포함 - 의사결정 관련 코드를 담당
  • StateLeess - 서비스 자체는 상태를 가지지 않는다.
  • 여러 애그리거트 간 연산 - 둘 이상의 애그리거트를 다루는 로직 처리

응용 서비스 정의

애그리거트와 도메인 서비스에 구현된 도메인 기능을 직접적으로 사용하는 서비스를 정의한다.

응용 서비스는 사용자가 요청한 기능을 실행한다.

특징으로는

  • 도메인 객체간의 흐름을 제어한다. (그렇기에 단순한 형태를 갖는다.)
  • 도메인 로직을 포함하지 않는다.
    • 응집도가 떨어질 수 있기 때문에 도메인 로직은 애그리거트에 구현한다.
  • 요청의 트랜잭션을 관리한다.

마치며

나는 지금까지 데이터 중심 모델(Anemic domain model)을 주로 사용하면서
DDD의 필요성을 느끼지 못했었다.
하지만 응집도가 떨어진 몇몇 코드들을 수정하면서 DDD에 관심을 갖게되었다.
이전까지는 굳이?? 라는 생각이 지배적이었다.

현재 내가 이해한 바를 정리한 것이라 내용이 다소 빈약할 수 있고, 다르거나 잘못 알고 있는 내용이 있을 수 있다.
앞으로도 관심을 갖고 학습한 뒤에 다음에 다시 한번 더 정리해볼 생각이다.
이후에는 에릭 에반스의 DDD 책을 읽어볼 생각이다.

참고 자료

최범균 님의 <도메인주도개발 시작하기>
NHN Cloud 정명주 님의 <DDD 뭣이 중헌디?>

profile
산입니다.

4개의 댓글

comment-user-thumbnail
2024년 8월 27일

좋은 리뷰 감사해요😊

1개의 답글
comment-user-thumbnail
2024년 10월 14일

LGTM!

1개의 답글