DDD Start! - 3장 정리

UkJJang·2021년 10월 6일
0

애그리거트

  • 복잡한 도메인을 이해하고 관리하기 쉬운 단위로 만들려면 상위 수준에서 모델을 조망할 수 있는 방법이 필요하다 그 방법이 애그리거트이다.
  • 복잡한 관련된 객체를 하나의 군으로 묶어준다.
  • 수많은 애그리거트로 묶어서 바라보면 좀 더 상위수준에서 도메인 모델 간의 관계를 파악할 수 있다.

  • 이러한 구조로 정리하면 전반적인 관계를 이해하는데 도움이 된다.
  • 애그리거트는 모델을 이해하는데 도움을 줄 뿐만 아니라 일관성을 관리하는 기준이 된다. 따라서 모델을 보다 잘 이해할 수 있고 애그리거트 단위로 일관성을 관리하기 때문에 복잡한 도메인을 단순한 구조로 만들어준다. 복잡도가 낮아지는 만큼 도메인 기능을 확장하고 변경하는 데 필요한 노력이 줄어든다.
  • 한 애그리거트에 속한 객체는 다른 애그리거트에 속하지 않는다. 애그리거트는 독립된 객체 군이며 각 에그리거트는 자기 자신을 관리할 뿐 다른 애그리거트를 관리하지 않는다. 이러한 경계를 설정할 때 기본이 되는 것은 도메인 규칙과 요구사항이다. 도메인 규칙에 따라 함께 생성되는 구성요소는 한 애그리거트에 속할 가능성이 높다.

애그리거트 루트

  • 애그리거트에 속한 모든 객체가 일관된 상태를 유지하려면 애그리거트 전체를 관리할 주체가 필요한데, 이 책임을 지는 것이 바로 애그리거트의 루트 엔티티이다.
  • 애그리거트 루트 엔티티는 애그리거트의 대표 엔티티로 애그리거트에 속한 객체는 애그리거트 루트 엔티티에 직접 또는 간접적으로 속한다.

도메인 규칙과 일관성

  • 애그리거트 루트가 단순히 애그리거트에 속한 객체를 포함하는 것으로 끝나는 것은 아니다. 애그리거트 루트의 핵심은 애그리거트의 일관성이 깨지지 않도록 하는 것이다.

  • 불필요한 중복을 피하고 애그리거트 루트를 통해서만 도메인 로직을 구현하게 만들려면 도메인 모델에 대해 두가지를 습관적으로 적용해야한다.

    1. 단순히 필드를 변경하는 set메서드를 public 으로 만들지 않는다.
    2. 밸류 타입은 불변으로 구현한다.
  • set 메서드를 개방시키면 도메인 객체가 아닌 응용영역이나 표현영역으로 분산되게 만드는 원인이 된다. 따라서 도메인 로직이 한곳에 응집되어 있지 않기 때문에 코드를 유지보수 할 때에도 분석하고 수정하는데 더 많은 시간을 들이게 된다.

  • 밸류 객체의 값을 변경할 수 없으면 애그리거트 루트에서 밸류 객체를 구해도 값을 변경할 수 없기 때문에 애그리거트 외부에서 밸류 객체의 상태를 변경할 수 없게 된다.

애그리거트 루트의 기능 구현

  • 애그리거트 루트는 애그리거트 내부의 다른 객체를 조합해서 기능을 완성한다.
  • 애그리거트 루트는 구성 요소의 상태만 참조하는 것이 아니라 기능 실행을 위임하기도 한다.

트랜잭션 범위

  • 트랜잭션 범위는 작을수록 좋다.
  • 한 트랜잭션에서는 하나의 애그리거트만 수정해야한다. 즉 다른 애그리거트를 변경하지 않는다는 것을 뜻함

리포지터리와 애그리거트

  • 애그리거트는 개념상 완전한 한 개의 도메인 모델을 표현하므로 객체의 영속성을 처리하는 리포지터리는 애그리거트 단위로 존재한다.
  • 어떤 기술을 이용해서 리포지터리를 구현하느냐에 따라 애그리거트의 구현도 영향을 받게된다.
  • JPA 하이버네이트를 사용하면 데이터베이스 관계형 모델에 객체 도메인을 맞춰야 하는 경우도 있다.
  • 애그리거트는 개념적으로 하나이므로 리포지터리는 애그리거트 전체를 저장소에 영속화 해야한다.

ID를 이용한 애그리거트 참조

  • 한 객체가 다른 객체를 참조하는 것처럼 애그리거트도 다른 애그리거트를 참조한다. 애그리거트의 관리 주체가 애그리거트 루트이므로 애그리거트에서 다른 애그리거트를 참조한다는 것은 애그리거트의 루트를 참조한다는 것과 같다.

  • ORM 기술 덕에 애그리거트 루트에 대한 참조를 쉽게 구현할 수 있고 필드를 이용한 애그리거트 참조를 사용하면 다른 애그리거트의 데이터를 객체 탐색을 통해 조회할 수 있다. 하지만 필드를 이용한 애그리거트 참조는 문제가 있다.

    1. 편한 탐색 오용
    2. 성능에 대한 고민
    3. 확장 어려움
  • 이러한 문제를 해결하기 위해 ID를 이용해서 다른 애그리거트를 참조하는 것이다.

  • ID를 이용한 참조는 DB 테이블에서의 외래키를 사용해서 참조하는 것과 비슷하게 다른 애그리거트를 참조할 때 ID 참조를 사용한다는 점이다. 단 애그리거트 내의 엔티티를 참조할 때는 객체 래퍼런스로 참조한다.

  • ID 참조를 사용하면 모든 객체가 참조로 연결되지 않고 한 애그리거트에 속한 객체들만 참조로 연결된다. 이는 애그리거트의 경계를 명확히하고 애그리거트 간 물리적인 연결을 제거하기 때문에 모델의 복잡도를 낮춰준다. 또한 애그리거트 간의 의존을 제거하므로 응집도를 높여주는 효과도 있다.

profile
꾸준하게 성실하게

0개의 댓글