Open rhakdnj opened 1 month ago
객체의 연관관계(association)를 최소화하면 탐색이 단순해지는 이점이 있으나 현실 세계는 그렇게 호락호락하지 않다.
그래서 객체의 연관관계를 있는 그대로 표현하게 되면 시스템이 상당히 복잡해지게 된다.
이런 복잡한 관계의 객체들을 그대로 사용하지 않고 묶어서 경계(boundary)를 설정해 주면 이해하기가 더 수월해지는데 이렇게 묶인 단위들을 aggregate라고 할 수 있다.
DB에서 Person 객체를 삭제한다고 가정해 보자.
이런 Person 객체는 보통 이름, 생년월일, 주소 등과 같은 속성을 갖는다. 시스템에서 Person을 삭제하면 이런 속성들도 자연스럽게 삭제된다.
하지만 주소의 경우 다른 Person 객체도 동일 주소를 참조하고 있다면 문제가 될 수 있다. 객체 변경의 범위를 명확히 하지 않으면 시스템이 커질 때 문제가 될 수 있다.
물론 DB의 rollback이나 lock과 같은 기술적인 해법을 통해 일관성을 보장해 줄 수 있지만 기본적인 이는 모델링 문제의 해법을 간과한 것이다.
그렇다면 FK가 걸려있는 테이블만 가지고 있으면 되는 것이 아닌가?
따라서 데이터 변경의 단위로 다루는 연관 객체의 묶음 즉 범위(boundary)가 필요하다. 이를 aggregate라고 하며 아래와 같은 특징을 갖는다.
Aggregate를 구현할 때 위와 같은 트랜잭션에도 몇 가지 규칙이 적용된다.
생명주기 동안 무결성을 유지해야 하며 생명주기를 관리해주어서 모델이 난해해지는 것을 방지한다.
DDD에서는 이를 해결하기 위해 Aggregate(집합체), Factory, Repository 3 가지 패턴을 제시한다.
Aggregate: 도메인 객체의 무결성을 유지하며 소유권과 경계(boundary)를 명확하게 해준다. 또한 객체간의 연관관계(association)이 혼란스럽지 않도록 해준다.
Factory: 복잡한 객체 및 Aggregate를 생성하고 재구성하며 내부 구조를 캡슐화한다.
Repository: 생명주기의 중간과 마지막을 담당한다. infrastructure 계층을 캡슐화하며, 영속 객체를 조회한다.