222. 애그리게이트 (Aggregate) - 도메인 주도 설계(DDD) 데이터 변경 단위 객체 묶음 루트 엔티티(Root Entity) 트랜잭션 경계 일관성
핵심 인사이트: (219번 DDD 심화 3) '주문'을 하려면 엑셀 칸이 3개 필요하다.
[주문서]객체,[주문_상품_목록]객체,[배송_주소]객체다. 이 3개는 한 몸통이라 무조건 같이 움직여야 한다. 근데 개발자 철수가 멍청하게[배송_주소]객체만 혼자 몰래 끄집어내서 자기 맘대로 주소를 바꿔버렸다! 나중에 결제팀이[주문서]를 확인해 보니 주소가 앞뒤가 안 맞아 배송이 증발하는 대참사가 터졌다. 에릭 에반스가 소리쳤다. "야! 이 3개 객체를 거대한 '비닐봉지(애그리게이트)' 하나에 통째로 쑤셔 담고 입구를 콱 묶어버려!! 그리고 비닐봉지 바깥에는 대장인[주문서]객체(루트 엔티티)의 머리통만 쏙 빼놔!! 밖에서 주소를 바꾸든 목록을 바꾸든 맘대로 못 건드려! 무조건 봉지 밖으로 튀어나온 대장([주문서])의 멱살을 잡고 '대장님, 주소 좀 바꿔주십쇼'라고 명령하게 만들어!! 그래야 대장이 전체 일관성을 검사하고 안전하게 고쳐주잖아!!" 흩어진 객체들을 하나의 트랜잭션 운명 공동체로 묶어버린 철통 방어선, 애그리게이트다.
Ⅰ. 미로처럼 얽힌 객체들의 무법지대 (도메인 복잡성)
- 실무의 도메인(비즈니스) 모델을 만들면 자바 클래스(객체)가 수백 개 쏟아집니다.
- 객체들끼리 거미줄처럼 화살표(참조)가 얽혀 있습니다. 아무나 아무 객체나 직접 끄집어내서 값(데이터)을 고치다 보면, **"주문 총액은 5만 원인데, 주문 상품 2개의 합은 3만 원인" 논리적 모순 상태(무결성 붕괴)**가 필연적으로 터집니다.
Ⅱ. 애그리게이트 (Aggregate)의 개념 🌟
- 개념: 관련된 여러 도메인 객체들(엔티티와 값 객체들)을 논리적으로 하나의 '거대한 군집(덩어리)'으로 묶어낸 것입니다.
- 이 비닐봉지로 묶인 군집은 데이터가 변경될 때 **무조건 다 같이 살고 다 같이 죽는 '하나의 트랜잭션 변경 단위'**로 작동하며 데이터의 일관성을 완벽하게 지켜냅니다.
Ⅲ. 애그리게이트를 굴리는 3대 독재 법칙 🌟 핵심 기출 🌟
1. 애그리게이트 루트 (Aggregate Root) - "절대 군주"
- 비닐봉지 안에는 여러 객체가 있지만, 그중 대장(Root Entity)은 딱 1명만 존재합니다. (예:
주문서(Order)) - 봉지 안의 쩌리 객체들(예:
주문_항목(OrderLine),배송_주소(ShippingInfo))은 대장의 부하들입니다.
2. 외부의 직접 접근 절대 금지 (캡슐화의 극의)
- 외부 세계(다른 애그리게이트나 서비스)는 봉지 안의 쩌리 객체(
주문_항목)를 직접 찌르거나 값을 가져올 수 없습니다! (직접 참조 금지) - 명령 체계: 외부에서 배송 주소를 바꾸고 싶으면, 무조건 밖으로 머리를 내밀고 있는 대장(
주문서 Root)에게만 말을 걸어야 합니다.order.changeShippingAddress("서울") - 효과: 대장이 명령을 받으면, 대장 스스로가 "어? 이 주문 이미 배송 출발했네? 주소 변경 불가!"라고 전체 비즈니스 규칙(무결성)을 한곳에서 완벽하게 검사한 뒤 쩌리의 값을 안전하게 바꿔줍니다.
3. 1 트랜잭션 = 1 애그리게이트 변경 원칙 🌟
- (가장 중요한 MSA 시대의 실무 룰) 하나의 트랜잭션 안에서는 오직 딱 1개의 애그리게이트(비닐봉지 1개)의 데이터만 고쳐야 합니다.
- "내가 결제를 하면서 동시에 회원의 포인트 봉지도 같이 수정할래!" ➜ 절대 안 됩니다! (나중에 DB가 2개로 찢어지는 MSA 환경에서 분산 트랜잭션 헬게이트가 열립니다.)
- 만약 회원 포인트도 올려야 한다면? 결제 봉지만 수정하고 끝낸 뒤, 214번처럼 "결제 끝났음!" 이라는 이벤트(쪽지)를 비동기로 날려서(EDA), 회원 애그리게이트가 그 쪽지를 보고 스스로 포인트를 올리게끔 설계해야만 시스템이 우주 끝까지 확장될 수 있습니다.
Ⅳ. 도입 효과
- 수백 개의 더러운 객체 거미줄이 수십 개의 깔끔한 비닐봉지(애그리게이트) 단위로 압축되어 아키텍처가 미치도록 단순하고 직관적으로 변합니다. (복잡도 감소)
📢 섹션 요약 비유: 도메인의 수많은 객체들은 **'자동차를 구성하는 수만 개의 부품(바퀴, 엔진, 핸들)'**입니다. 만약 멍청한 정비사가 바퀴(내부 객체)만 쏙 빼서 자전거 바퀴로 맘대로 갈아 끼우면, 자동차는 달릴 수 없는 고철 덩어리(데이터 모순)가 됩니다. **애그리게이트(Aggregate)**는 이 수만 개의 부품을 조립해 **'완성된 자동차 1대(하나의 군집)'**로 꽁꽁 묶어 철판 껍데기(비닐봉지)를 씌워버린 것입니다. 이 껍데기 밖으로 튀어나온 유일한 대장 조종 장치는 **'운전대(애그리게이트 루트)'**뿐입니다. 외부의 운전자는 절대 엔진이나 바퀴를 직접 손으로 잡아 돌릴 수 없습니다. 무조건 운전대(루트 엔티티)를 돌려서 명령을 내려야만, 자동차의 내부 컴퓨터(루트)가 브레이크와 바퀴의 상태(전체 일관성 규칙)를 완벽하게 검사한 뒤 안전하게 바퀴를 꺾어줍니다. 관련된 부품들을 다 같이 살고 다 같이 죽는 하나의 완벽한 운명 공동체(트랜잭션 단위)로 묶어, 외부의 무식한 조작으로부터 시스템의 붕괴를 철통같이 막아내는 객체지향 설계의 진수입니다.