STUDY/DDD
-
[도메인 주도 개발 시작하기] 11. CQRSSTUDY/DDD 2023. 1. 10. 00:35
시스템이 제공하는 기능은 크게 두 가지로 나눌 수 있다. 상태를 변경하는 기능 상태 정보를 조회하는 기능 상태를 변경하는 범위와 상태를 조회하는 범위가 정확하게 일치하지 않기 때문에 단일 모델로 두 종류의 기능을 구현하면 모델이 불필요하게 복잡해진다. 단일 모델을 사용할 떄 발생하는 복잡도를 해결하기 위해 CQRS를 사용한다. CQRS는 Command Query Responsibility Segregation의 약자로, 상태를 변경하는 명령을 위한 모델과 상태를 제공하는 조회를 위한 모델을 분리하는 패턴이다. CQRS는 복잡한 도메인에 적합하다. 도메인이 복잡해질수록 명령 기능과 조회 기능이 다루는 데이터 범위에 차이가 난다. CQRS를 사용하면 각 모델에 맞는 구현 기술을 선택할 수 있다. 예를 들어 ..
-
[도메인 주도 개발 시작하기] 10. 이벤트STUDY/DDD 2023. 1. 10. 00:13
1. 시스템 간 강결합 문제 쇼핑몰에서 구매를 취소하면 환불을 처리해야 한다. 이때 환불 기능을 실행하는 주체는 주문 도메인 엔티티가 될 수 있고, 응용 서비스에서 환불 기능을 실행할 수도 있다. 1. 도메인 엔티티에서 실행 public class Order { ... // 외부 서비스를 실행하기 위해 도메인 서비스를 파라미터로 전달받음 public void cancel(RefundService refundService) { verifyNotYetShipped(); this.state = OrderState.CANCELED; this.refundStatus = State.REFUND_STARTED; try { refundService.refund(getPaymentId()); this.refundStat..
-
[도메인 주도 개발 시작하기] 9. 도메인 모델과 바운디드 컨텍스트STUDY/DDD 2022. 12. 27. 22:07
1. 도메인 모델과 경계 한 도메인은 여러 하위 도메인으로 구분되기 때문에 한 개의 모델로 여러 하위 도메인을 모두 표현하려고 시도하면 오히려 모든 하위 도메인에 맞지 않는 모델을 만들게 된다. 또한 논리적으로 같은 존재처럼 보이지만 하위 도메인에 따라 다른 용어를 사용하는 경우도 존재한다. 하위 도메인마다 같은 용어라도 의미가 다르고 같은 대상이라도 지칭하는 용어가 다를 수 있기 때문에 한 개의 모델로 모든 하위 도메인을 표현하려는 시도는 올바른 방법이 아니며 표현할 수도 없다. 하위 도메인마다 사용하는 용어가 다르기 때문에 올바른 도메인 모델을 개발하려면 하위 도메인마다 모델을 만들어야하고, 각 모델은 명시적으로 구분되는 경계를 가져서 섞이지 않도록 해야 한다. 여러 하위 도메인의 모델이 섞이면 모델..
-
[도메인 주도 개발 시작하기] 8. 애그리거트 트랜잭션 관리STUDY/DDD 2022. 12. 19. 23:22
1. 애그리거트와 트랜잭션 운영자와 고객이 동시에 한 주문 애그리거트를 수정할 경우, 트랜잭션마다 리포지터리는 새로운 애그리거트 객체를 생성하므로 운영자 스레드와 고객 스레드는 같은 주문 애그리거트를 나타내는 다른 객체를 구하게 된다. 운영자 스레드와 고객 스레드는 개념적으로 동일한 애그리거트지만 물리적으로 서로 다른 애그리거트 객체를 사용하므로 서로 영향을 주지 않는다. 예를들어 운영자가 주문 애그리거트 객체를 배송 상태로 변경하더라도 고객 스레드에서 사용하는 객체에 영향을 주지 않으므로, 고객 입장에서는 배송 상태 전이므로 배송지 정보를 변경할 수 있다. 이 상황에서 두 스레드는 각각 트랜잭션을 커밋할 때 수정한 내용을 DB에 반영한다, 이 시점에 배송 상태로 바뀌고 배송지 정보도 바뀌게 된다. 여기..
-
[도메인 주도 개발 시작하기] 7. 도메인 서비스STUDY/DDD 2022. 12. 19. 22:16
1. 여러 애그리거트가 필요한 기능 도메인 영역의 코드를 작성하다 보면, 한 애그리거트로 기능을 구현할 수 없을 때가 있다. 대표적인 예로 결제 금액 계산 로직이 있다. 상품 애그리거트 : 구매하는 상품의 가격이 필요하다. 또한 상품에 따라 배송비가 추가되기도 한다. 주문 애그리거트 : 상품별로 구매 개수가 필요하다. 할인 쿠폰 애그리거트 : 쿠폰별로 지정한 할인 금애리나 비율에 따라 주문 총 금액을 할인한다.... 회원 애그리거트 : 회원 등급에 따라 추가 할인이 가능하다. 총 결제 금액을 계산하기 위한 할인 쿠폰 적용, 추가 할인 적용 등을 하나의(예를 들어, 주문) 애그리거트를 정해 그곳에 모두 구현할 수 있지만, 한 애그리거트에 애매한 도메인 기능을 억지로 구현할 경우 자신의 책임 범위를 넘어서는..
-
[도메인 주도 개발 시작하기] 6. 응용 서비스와 표현 영역STUDY/DDD 2022. 12. 12. 22:56
1. 표현 영역과 응용 영역 사용자에게 기능을 제공하려면 도메인과 사용자를 연결해 줄 표현 영역과 응용 영역이 필요하다. 표현 영역은 사용자의 요청을 해석한다. 사용자의 HTTP 요청은 표현 영역에 전달되고, 표현 영역은 URL, 요청 파라미터, 쿠키, 헤더 등을 이용해서 사용자가 실행하고 싶은 기능을 판별하고 그 기능을 제공하는 응용 서비스를 실행한다. 응용 영역은 실제 사용자가 원하는 기능을 제공하는 서비스가 위치해 있다. 응용 서비스는 기능을 실행하는 데 필요한 입력 값을 메서드 인자로 받고 실행 결과를 리턴한다. 응용 서비스의 메서드 파라미터와 표현 영역이 사용자로부터 전달받은 데이터는 형식이 일치하지 않기 때문에 표현 영역은 응용 서비스가 요구하는 형식으로 사용자 요청을 변환한다. 응용 서비스를..
-
[도메인 주도 개발 시작하기] 4. 리포지터리와 모델 구현STUDY/DDD 2022. 12. 1. 00:32
1. JPA를 이용한 리포지터리 구현 1-1. 모듈 위치 리포지터리 인터페이스는 애그리거트와 같이 도메인 영역에 속하고, 리포지터리를 구현한 클래스는 인프라스트럭처 영역에 속한다. 리포지터리 구현 클래스를 인프라스트럭처 영역에 위치시켜서 인프라스트럭처에 대한 의존을 낮춰야 한다. 1-2. 리포지터리 기본 기능 구현 ID로 애그리거트 조회하기 애그리거트 저장하기 public interface OrderReporsitory { // Optional findById(OrderNo no); null을 사용하기 않기 위해 Optional 사용 Order findById(OrderNo no); // ID에 해당하는 애그리거트 반환 void save(Order order); // 애그리거트 저장 } 리포지터리는 두 ..
-
[도메인 주도 개발 시작하기] 3. 애그리거트STUDY/DDD 2022. 11. 18. 10:02
1. 애그리거트 상위 수준에서 모델을 정리하면 도메인 모델의 복잡한 관계를 이해하는 데 도움이 된다. 개별 객체 단위로 정리하게 되면 상위 모델에 대한 이해 없이 상위 수준에서 개념을 파악하기 어려워진다. 더 많은 코드를 보고 도메인 전문가와 더 많은 대화를 나눠야 상위 수준에서 모델 간의 관계가 이해된다. 백 개 이상의 테이블을 한 장의 ERD에 모두 표시하면 개별 테이블 간의 관계를 파악하느라 큰 틀에서 데이터 구조를 이해하는 데 어려움을 겪게 되는 것처럼, 도메인 객체 모델이 복잡해지면 개별 구성요소 위주로 모델을 이해하게 되고 전반적인 구조나 큰 수준에서 도메인 간의 관계를 파악하기 어려워진다. 주요 도메인 요소 간의 관계를 파악하기 어렵다는 것은 코드를 변경하고 확장하는 것이 어려워진다는 것을 ..