블로그에 게시하는 위 글은 전체적인 내용 정리가 아닌
책을 읽으면서 새로 알게된 내용이나 제가 중요하다고 생각하는 내용을 정리한 글입니다.
코드 변경/확장을 쉽게 하기 위해 주요 도메인 개념 간의 관계를 파악해야하는데,
이 관계들을 이해하고 관리하게 쉽게 상위 수준에서 모델을 조망하는 것이 애그리거트이다.
애그리거트를 사용하면 좋은 점
애그리거트의 특징
한 애그리거트 안의 객체들은 동일하거나 유사한 라이프 사이클을 가짐
경계를 가지며 독립적임
A가 B를 갖는다 = A, B는 하나의 애그리거트에 속하는 가능성이 높다 (예외 경우 O)
예외 경우
상품 상세페이지에서 리뷰를 보여줘야하지만, 상품이 변경된다고 리뷰가 변경 X
애그리거트 전체를 관리하는 주체를 애그리거트 루트라고 한다.
애그리거트에 속한 객체는 루트에 직/간접적으로 속한다.
애그리거트 루트의 핵심 역할은 애그리거트의 일관성이 깨지지 않도록 하는 것이다.
애그리거트 루트가 할 수 있는 일
트랜잭션 범위는 작을 수록 좋다.
또한 한 트랜잭션에서는 한 개의 애그리거트만 수정해야한다.
한 애그리거트에서 다른 애그리거트에 대해 접근을 하는 것은 굉장히 좋지 않다.
(다만 팀표준, 기술 제약, UI 구현의 편리 등의 상황일 땐 어쩔 수 없이 제외한다)
차라리 응용 서비스에서 두 애그리거트를 수정하도록 구현해야하는게 맞다.
리포지터리는 애그리거트(애그리거트 루트) 단위로 존재해야하며
애그리거트 전체를 저장소에 영속화 해야한다.
다른 애그리거트를 직접 참조하기 보단 간접적으로 id를 참조하는것이 훨씬 좋다.
N+1 문제가 발생하는 상황이 생기는 경우가 있는데, (ex. 주문 목록을 보여줄 때 상품 애그리거트, 회원 애그리거트를 함께 읽어야할 때) 이럴 때는 전용 조회 쿼리를 사용하는게 더 좋다. (ex. mybatis)
개념적으로 1:N 관계여도, 실제 구현에 반영하는 경우는 드물다.
차라리 N:M을 더 많이 사용
애그리거트를 만드는 팩토리 메소드를 만들고,
서비스단에서는 그 메소드를 사용해서 애그리거트를 만들게 하는게 더 좋다.
서비스 단에서 도메인의 로직이 웬만하면 노출되지 않게 하는게 중요하다.