서동우 튜터님 특강
- 관계형 데이터베이스에서는 연관관계를 FK(외래키)를 통해 달성
- 여러 테이블이 FK를 통해 연관관계를 맺고 있다면, 조인을 사용하여 데이터를 연결하고 원하는 정보를 가져올 수 있음
- 그러나 객체 관점에서는? →객체 그래프 탐색으로 인한 n+1 문제 발생
🤔 RDBMS의 관점과 객체 관점이 맞지 않음
→ ORM : RDMBS와 객체, 둘의 구조가 달라서 미스매치가 발생하는 것을 해결하기 위해 SQL을 자동으로 생성하고, 객체와 데이터베이스를 연결
이전까지는 ERD설계를 통해 외래키를 설정하고, 외래키 기반으로 연관관계를 설정하여 엔티티를 구현했음
연관관계에서도 종속적인 관계가 있음
- 영속성 전이(Cascade)가 가능
- 라이프사이클을 공유
- ex) 주문 아이템은 주문 없이는 존재할 수 없다
- ex) 주문 아이템은 주문 없이는 존재할 수 없다
독립적인 관계도 있음
- 주문아이템-상품 : 상품이 먼저 만들어 진 후 주문이 생성될때 상품을 가져옴 → 생명주기가 다름
- 주문 - 유저 : 유저가 삭제된다고 해서 주문에 영향이 미치면 안됨
JPA는 종속적인 관계에 대한 기능을 지원하고 있음
ex) 주문을 생성할때 주문 아이템을 생성함, 주문이 삭제될 때 주문 아이템도 삭제함 등..
이렇게 도메인이 확장되어 복잡하다면 어떻게 해결할 수 있을까? → DDD
도메인 주도 설계 (DDD)
도메인을 중심으로 소프트웨어를 설계하는 것
바운디드 컨텍스트(Bounded Context)
큰 시스템을 여러 개의 작은 컨텍스트로 나누어 각 컨텍스트 내에서 특정 비즈니스 규칙과 데이터 모델이 적용하는 것을 의미
각 컨텍스트는 독립적으로 설계되고 구현 됨.
각 컨텍스트가 독립적으로 동작하도록 설계 → 전체 시스템의 복잡성을 줄이고 유연성을 높임
컨텍스트 간에는 인터페이스를 통해 상호작용
패키지구조 - 4계층 구조
presentation - application - domain - infrastructure
: DDD에서 가져가는 기본적인 계층 구조
모놀리식 → MSA 전환을 위한 구조
주문이 공통모듈을 통해 상품을 호출하게 함
그 결과 주문-상품 의존하는 코드가 없음 → 서비스를 따로 분리할 수 있음
애그리거트(Aggregate)
도메인 모델에서 논리적으로 하나의 단위로 묶여야 하는 객체들의 집합
* 애그리거트 루트 : 애그리커드를 대표하는 객체, 애그리거트의 유일한 진입점(Entry Point) - ex)주문, 유저, 가게..
애그리거트는 라이프사이클을 공유함 → 애그리거트를 트랜잭션으로 묶음
🤔 애그리커드와 루트가 필요한 이유?
- 데이터 일관성 유지
- 변경 범위 (트랜잭션) 제어
- 도메인 모델 명확하게 만들기
- 엔티티 간 직접 참조 방지
- 데이터 저장소(Repository)와의 관계 정리
데이터 저장소(Respository)와의 관계 정리
애그리거트 단위로 데이터 저장소 관리 - 데이터의 무결성 보장
* OrderRespository는 Order를 저장, Order 내부의 OrderItem도 함께 저장 (Cascade.Persist) - 영속성 전이
→ 별도의 OrderItemRepository는 만들지 않음
* OrderitemRepository가 따로 있으면 Order 없이 OrderItem이 변경 될 가능성이 있음
→ 데이터가 엉켜서 일관성이 깨질 위험이 있음
public Order(List<OrderItem> orderItems) { validateOrderItems(orderItems); this.orderItems = orderItems; }
Order의 생성은 항상 OrderItems와 함께
public void validateOrderItems(List<OrderItem> orderItems) { if(orderItem == null || orderItems.isEmpty()) { throw new IllegalArgumentException("주문 항목은 비어 있을 수 없습니다."); } if (orderItems.size() > MAX_ORDER_ITEMS) { // OrderItem 갯수가 10개를 초과하면 Order 자체를 만들면 안됨 throw new IllegalArgumentException("주문 상품 수가 " + MAX_ORDER_ITEMS + "개를 초과하였습니다."); } }
'Back-End > DDD' 카테고리의 다른 글
DIP (Dependency Inversion Principle, 의존성 역전 원칙) (0) | 2025.03.15 |
---|---|
아키텍처 (0) | 2025.03.15 |
도메인 (0) | 2025.03.14 |