
DDD에 관해 꽤나 주관적인 해석을 담고 있습니다.
DDD와 객체 협업에 대한 개인적인 생각
나는 DDD를 좋아한다. 그 이유는 하나의 객체가 다루기 어려운 로직을 여러 객체의 협업을 통해 풀어나갈 수 있기 때문이다.
실제 비즈니스 로직을 모델링하다 보면, 단일 객체(여기서 말하는 객체란 엔티티)는 생각보다 많은 역할을 하지 못한다.
한 객체가 하는 일은 단순할 때가 많으며, 단순한 CRUD 수준이라면 유닛 테스트조차 무색하게 느껴지곤 한다.
하지만 여러 객체 간의 협업으로 모델링하면 비즈니스의 본질이 다루기 용이하고, 비로소 유닛 테스트가 검증해야 할 복잡도도 적절한 수준이 된다.
(개인적으로 나는 로직이 충분히 복잡하지 않다면 테스트 코드의 가성비가 떨어진다고 생각한다.)
도메인 개요: 오징어 게임 조직 모델링
핵심 엔티티는 아래와 같다.
동그라미가 치명적인 실수를 하면 자신의 상급자인 세모와 네모에게도 영향을 미친다.
- □ 네모, 관리자 (Manager):
- 속성: 총 조직원 수 (세모와 동그라미 포함)
- 관계: 다수의 세모를 관리
- 행위: 소속 동그라미의 실수 발생 시 총 조직원 수 감소
- △ 세모, 병정 (Soldier):
- 속성: 척살한 동그라미 수
- 관계: 다수의 동그라미를 관리
- 행위: 소속 동그라미의 실수 발생 시 자신의 척살한 동그라미 수를 증가시킴
- ○ 동그라미, 일꾼 (Worker):
- 상태:
- ACTIVE (내부 활동)
- RESTING (휴식)
- ELIMINATED (제거됨)
- 행위: 치명적인 실수를 한 경우 척살 됨(상태를 ELIMINATED로 변경, 즉 삭제하지 않고 남김)
- 상태:
코드 설계
나는 Infrastructure API가 크게 두 가지로 나뉜다고 생각한다.
하나는 조회를 위한 API, 하나는 데이터 변경을 위한 API.
조회의 성격도 두 가지로 나뉜다. 복잡한 조회를 위한 것과 변경을 위한 조회.
나 같은 경우 아래 관래로 사용한다.
- 조회 API에서 사용할 역할
- ***Query
- 변경을 위한 조회 역할
- *** Repository
***Repository는 애그리거트를 조회하는 역할을 하며, 단순한 CRUD를 넘어서는 전략이 필요하다.
예를 들어, 네모 → 세모→ 동그라미 연관관계가 모두 List로 잡혀있고 FetchJoin으로 조회할 경우 MultipleBagFetchException가 발생한다.
이를 해결하려면 아래와 같은 방법이 필요하다.
- List 대신 Set을 사용하여 여러 개의 컬렉션을 동시에 fetch join 가능하도록 변경
- 조회 쿼리를 분리하여 개별적으로 로딩
- FetchMode.SUBSELECT 사용 (서브쿼리를 활용한 N+1 문제 해결)
또한, 전통적인 DDD에서는 관련된 모든 객체를 조회하지만,
성능상의 이유로 혹은 비즈니스 모델 특성상 특정 속성만 가진 객체를 조회해야 하는 경우도 많다.
이러한 복잡한 처리 또한 Repository에서 담당하면 된다.
상세 코드
동그라미를 조회할 때 세모와 네모도 같이 조회한다.
이때 동그라미는 살아있는 것만 조회한다.
그리고 동그라미를 척살한다.
그러면 세모는 척살 수를 증가시키고 네모는 조직원 수를 감소시킨다.
위 코드는 Aggregate가 동그라미로 잡혀있지만, 보통 나는 가장 상위의 객체를 Aggregate로 잡곤 한다. 그 이유는 가장 많은 처리를 할 수 있을 것 같아서이다.
아래 깃허브에 위에서 다룬 내용의 코드를 작성해두었다.
blog-topics/jpa-multi-entity at main · progress0407/blog-topics
블로그 주제 작성을 위한 리포지토리. Contribute to progress0407/blog-topics development by creating an account on GitHub.
github.com
'Back-end > DDD, Hexagonal ..' 카테고리의 다른 글
DDD 세미나에서 느낀 것들 (0) | 2024.03.31 |
---|---|
헥사고날 퐁당 후기 (0) | 2024.01.29 |
hi hello... World >< 가장 아름다운 하나의 해답이 존재한다
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!