Clean Spring ‐ Designing a Consistent Domain Model with Aggregates - thought-corner/backend-roadmap GitHub Wiki

  • 도메인 주도 개발(DDD)에 소개된 도메인 모델 구성 요소/패턴의 하나이다.
  • 데이터 변경의 목적을 위해 하나의 단위로 취급되는 연관된 객체들의 클러스터이다.
  • 루트(root)와 경계(boundary)를 가진다.
  • 경계 내부에는 엔티티와 값 객체가 하나 또는 여러 개가 존재할 수 있다.
  • 애그리거트 루트는 내부에 포함된 단일 엔티티이다.

애그리거트의 특징

  • 데이터 변경 시 하나의 단위로 취급한다. 즉, 데이터 변경의 일관성을 유지한다.
  • 루트를 통한 접근 제어가 가능하다. 즉, 외부 객체는 루트 엔티티에만 참조를 가질 수 있다.
  • 데이터 일관성 유지
    • 경계 내의 어떤 변경 사항이 있을 때, 전체 애그리거트의 모든 불변식이 충족되어야 한다.
    • 애그리거트를 넘어서는 불변식은 이벤트나 배치 등을 통해 특정 시간 내에 해결할 수 있다.
  • 검색 및 접근 방식 : 리포지토리를 통해서 애그리거트 루트만 직접 얻을 수 있다.
    • 내부 엔티티는 루트로부터 연관관계를 통해서 접근한다.
  • 생명주기 관리 캡슐화 : Factory와 Repository를 이용해서 객체들을 생명주기에 걸쳐 체계적이고 의미있는 단위로 조작한다.

애그리거트의 목표

  • 일관성 유지 : 객체 그룹에 적용되는 불변식을 유지하는 수단이다.
  • 이해 용이성 : 객체의 시작과 끝을 명확히 해서 모델을 더 쉽게 이해하게 한다.
  • 트랜잭션 및 동시성 관리 : 트랜잭션 범위왕 데이터 일관성 유지 방법 제공
  • 모델 단순화 : 연관 관계 탐색을 제한하고 루트를 통해서만 접근하도록 해준다.
  • Factory와 Repository가 복잡한 생명주기 전환을 캡슐화하는 단위가 되도록 한다.

애그리거트 설계 적용과 적용 어려움

  • JPA의 cascading을 적절하게 활용한다.
  • 리포지토리는 애그리거트 단위로 만든다.
    • Spring Data JPA의 핵심 원칙
    • Repository<T, ID> : T = Aggregate Root
    • 리포지토리 리턴 타입은 애그리거트 루트
  • 가능하다면 하나의 트랜잭션에 하나의 애그리거트만 변경한다.
  • 다른 애그리거트의 참조는 애그리거트 루트에 대해서만 한다. 연관관계 애그리거트 루트의 레퍼런스 대신 루트의 ID 값만 저장하도록 한다.
  • 적절한 애그리거트 경계를 선택하는 것은 꽤 어렵다. 개발하면서 애그리거트의 범위가 달라지기 때문이다.
  • 성능에 부담을 주게 된다. lazy loading의 도움이 필요하다.
  • 내부 엔티티로의 직접 접근이나 여러 애그리거트를 한 번에 조회하는 기능이 필요한 경우가 있다.
  • 도메인 이벤트와 최종적 일관성의 사용이 요구된다.

헥사고날 아키텍처와 애그리거트

  • 애그리거트 단위로 애플리케이션(헥사곤)을 구성하는 방법이 유용하다.
  • 다른 애그리거트로의 접근은 애플리케이션 포트를 통해서 ID를 전달하는 방식으로 애플리케이션 내부 리포지토리에서 루트 엔티티를 조회하는 방식으로 이루어지게 강제할 수 있다.
  • 도메인 이벤트와 리스너를 이용해서 애그리거트 사이의 작업을 연결할 수도 있다. 이벤트에 필요한 애그리거트 루트 ID를 전달한다.
  • 애그리거트를 설계하고 각각을 독립적인 애플리케이션으로 분리한다.
⚠️ **GitHub.com Fallback** ⚠️