DDD(Domain Driven Design) 도메인 주도 개발


DDD(Domain Driven Design)란?

  • 도메인 주도 설계
  • 정교한 객체 시스템을 제작하는데 도움이 되는 원칙과 패턴의 집합이다.
  • 비즈니스 Domin별로 나누어 설계하는 방식이다.
  • 실세계에서 사건이 발생하는 집합인 Domain(도메인)을 중심으로 설계하는 방법이다.
    • 옷 쇼핑몰을 예를 들면, 손님들의 주문하는 도메인, 점주들이 관리하는 도메인 등이 있을 수 있다.
    • 이런한 도메인들이 서로 상호 작용을 하며 설계하는 것이 도메인 주도 설계이다.
  • 도메인 주도 설계에서 도메인은 각각 분리되어 있는데, 이런한 관점에서 MSA(MicroService Architecture)를 적용하면 용이한 설계를 할 수 있다.
  • DDD에서는 같은 객체들이 존재할 수 있는데, 예를 들어 옷 구매자의 입장에서는 (name, price)와 같은 객체 정보를 담지만, 판매자 입장에서는 (madeTie, Size, madeCounty) 등이 있을 수 있다. 즉, 문맥에 따라 객체의 역할이 발뀔 수 있는 것이 DDD이다.

Ubiquitous Language (유비쿼터스 랭귀지)

도메인에서 사용하는 용어를 코드에 반영하지 않으면 그 코드는 개발자에게 코드의 의미를 해석해야 하는 부담을 준다. 코드의 가독성을 높여서 코드를 분석하고 이해하는 시간을 절약, 용어가 정의 될 때마다 용어 사전에 이를 기록하고 명확하게 정의 함으로써 추후 또는 다른 사람들도 공통된 언어를 사용할 수 있도록 한다.

도메인이란?

  • 일반적인 요구사항, 소프트웨어로 해결하고자 하는 문제의 영역이다.
    • 온라인 서점 시스템을 구현한다고 할때, 온라인 서점이 도메인이 된다.
  • 한 도메인은 다시 여러개의 하위 도메인으로 나뉠 수 있다.
    • 온라인 서점의 하위 도메인은 상품, 회원, 주문, 정산, 배송 등이 된다.
  • 모든 도메인마다 고정된 하위 도메인이 존재하는 것은 아니다. 상황에 따라 달라진다.
    • 대상이 기업인지, 사용자인지 등등
  • 특정 도메인을 위한 소프트웨어라고 해서 도메인이 제공해야 할 모든 기능을 구현하는 것은 아니다.
    • 외부 업체의 배송 시스템이나, 결재 시스템 같은 것을 이용하기도 한다.

도메인 모델

  • 특정 도메인을 개념적으로 표현한 것이다.
  • 실제 세계를 반영은 하지만, 실제 세계의 복사본이 아니며, 실제 대상을 더 잘 이해할 수 있도록 추상화되고 구체화하는 것이다.
  • 이를 사용하면 여러 관계자들이 동일한 모습으로 도메인을 이해하고, 도메인 지식을 공유하는데 도움이 된다.
    • 도메인을 이해하려면 도메인이 제공하는 기능과 주요 데이터 구성을 파악해야 한다.
    • 보통은 기능과 데이터를 함께 보여주는 클래스 다이어그램이 적합하다.
    • 꼭 UML만 사용해야 하는 것은 아니다. 도메인을 이해하는데 도움이 된다면 표현 방식이 무엇인지는 중요하지 않다.
  • 여러 하위 도메인을 하나의 다이어그램에 모델링하면 안된다.
    • 각 하위 도메인마다 별도로 모델을 만들어야 한다.
    • 모델의 각 구성 요소는 특정 도메인을 한정할 때 비로서 의미가 완전해지기 때문이다.
      • 카탈로그의 상품과 배송의 상품은 다르다.

Entity, VO

  • Entity
    • 테이블 모델, 고유 식별자를 가진다.
    • 고유 식별자(primary Key)를 바탕으로 객체의 정체성을 부여한다.
  • VO(Value Object)
    • 데이터 표현 모델 식별자를 가지고 있지 않고 불변 타입이다.
    • 상태(Attribute)를 바탕으로 객체의 정체성을 부여한다.

Java로 쉽게 설명하자면, equals HashCode를 id로만 하면 Entity이고 상태에 대한 모든 정보로 하면 VO 이다.

도메인 애그리거트(Aggregate)

  • 서로 관련 있는 도메인 모델들의 집합, 연관 객체의 묶음을 애그리거트라고 한다.

애그리거트 루트

  • 애그리거트에 속한 객체가 일관된 상태를 유지하려면 애그리거트 전체를 관리할 주체가 필요하다.
  • 루트 엔티티는 애그리거트의 대표 엔티티로, 애그리거트에 속한 엔티티는 루트 엔티티에 직접 혹은 간접적으로 속한다.
    • 애그리거트 루트의 핵심 역할은 애그리거트의 일관성이 깨지지 않도록 조율하는 것이다.
    • 애그리거트 루트는 애그리거트가 제공해야 할 도메인 기능을 제공한다.
      • 주문 애그리거트의 루트 엔티티 Order는 관련 기능을 구혀한 메소드를 제공한다.
        • 배송지 변경, 상품 변경 등.

도메인 모델 패턴

  • 일반적인 어플리케이션의 아키텍처는 4가지 영역(계층)으로 구성된다.

Presentation: 표현(UI) 영역

  • 사용자의 요청을 받아 응용 영역에 전달한다.
  • 스프링 MVC 프레임워크가 표현 영역을 위한 기술에 해당된다.
  • 웹 애플맄이션에서 표현 영역의 사용자는 웹 브라우저를 사용하는 사람일 수도 있고, REST API를 호출하는 외부 시스템일 수도 있다.

Application: 응용 영역

  • 처리 결과를 다시 사용자에게 보여주는 역할을 한다.
  • 업무 로직을 직업 구현하지 않으며, 도메인 계층을 조합해서 기능을 실행한다.
  • 주로 도메인과 Repository를 바탕으로 실제 서비스(API)를 제공하는 계층이다.

Domain: 도메인 영역

  • 시스템이 제공할 도메인의 규칙을 구현한다.
  • Entity, VO(Value Object)를 활용하여 도메인 로직이 진행되는 계층이다.

Intrastructure: 인프라스트럭처 영역

  • 영속성을 구현하거나 외부 시스템과의 연동을 처리한다.
  • 즉, 외부와의 통신 DB, NoSQL, Messaging 등을 담당하는 계층이다.