책 정리/도메인 주도 개발 시작하기

책 정리/도메인 주도 개발 시작하기

Chapter 11. CQRS

단일 모델의 단점 주문 내역 조회 기능을 구현하려면 여러 애그리거트에서 데이터를 가져와야 한다. 예를 들면 Order에서 주문 정보를 가져와야 하고, Product에서 상품 이름을 가져와야 하고, Member에서 회원 이름과 ID를 가져와야 한다. 조회 시 여러 애그리거트의 데이터가 필요하면 구현 방법을 고민해야 한다. 식별자를 이용해 애그리거트를 참조하는 방식을 사용하면 즉시 로딩과 같은 JPA의 쿼리 관련 최적화 기능을 사용할 수 없다. 애그리거트 간 연관을 식별자가 아닌 직접 참조하는 방식으로 구현해도 고민이 생긴다. 같은 연관도 즉시 로딩이나 지연 로딩으로 처리해야하기 때문이다. 이런 고민이 발생하는 이유는 시스템 상태를 변경할 때와 조회할 때 단일 도메인 모델을 사용하기 때문이다. ORM 기법은..

책 정리/도메인 주도 개발 시작하기

Chapter 10. 이벤트

시스템 간 강결합 문제 쇼핑몰에서 구매를 취소하면 환불을 처리해야 한다. 이 때 환불 기능을 실행하는 주체는 주문 도메인 엔티티가 될 수 있다. 도메인 객체에서 환불 기능을 실행하려면 환불 기능을 제공하는 도메인 서비스를 인자로 받고 취소 도메인 기능에서 도메인 서비스를 실행해야 한다. public class Order { public void cancel(RefundService refundService){ // 취소 로직 // 환불 로직 // 외부 서비스에 의존하고 있음 refundService.refund(..) } } 보통 결제 시스템은 외부에 존재하므로 RefundService는 외부에 있는 결제 시스템이 제공하는 환불 서비스를 호출한다. 이 때 두 가지 문제가 발생할 수 있다. 첫 번째는 외부..

책 정리/도메인 주도 개발 시작하기

Chapter 9. 도메인 모델과 바운디드 컨텍스트

도메인 모델과 경계 처음 도메인 모델을 만들 때 빠지기 쉬운 함정이 도메인을 완벽하게 표현하는 단일 모델을 만드는 시도를 하는 것이다. 하지만 한 도메인은 다시 여러 하위 도메인으로 구분되기 때문에 한 개의 모델로 여러 하위 도메인을 모두 표현하려고 시도하면 오히려 모든 하위 도메인에 맞지 않은 모델을 만들게 된다. '상품'이라는 모델을 생각해보자. 카탈로그에서의 상품. 재고 관리에서의 상품. 주문에서의 상품. 배송에서의 상품. 이름만 같지 실제로 의미하는 것이 다르다. 이렇게 하위 도메인마다 같은 용어라도 의미가 다르기 때문에 한 개의 모델로 모든 하위 도메인을 표현하려는 시도는 올바른 방법이 아니며, 표현할 수도 없다. 하위 도메인마다 사용하는 용어가 다르기 때문에 올바른 도메인 모델을 개발하려면 하..

책 정리/도메인 주도 개발 시작하기

Chapter 8. 애그리거트 트랜잭션 관리

애그리거트와 트랜잭션 한 주문 애그리거트에 대해 운영자는 배송 상태로 변경할 때 사용자는 배송지 주소를 변경하면 어떻게 될까? 그림을 보면 운영자와 고객이 동시에 한 주문 애그리거트를 수정하는 과정을 보여준다. 트랜잭션마다 리포지터리는 새로운 애그리거트 객체를 생성하므로 운영자 스레드와 고객 스레드는 같은 주문 애그리거트를 나타내는 다른 객체를 구하게 된다. 운영자 스레드와 고객 스레드는 개념적으로 동일한 애그리거트지만 물리적으로 서로 다른 애그리거트 객체를 사용한다. 때문에 운영자 스레드가 주문 애그리거트 객체를 배송 상태로 변경하더라도 고객 스레드가 사용하는 주문 애그리거트 객체에는 영향을 주지 않는다. 문제점은 운영자는 기존 배송지 정보를 활용해 배송 상태로 변경했는데 그 사이 고객은 배송지 정보를..

책 정리/도메인 주도 개발 시작하기

Chapter 7. 도메인 서비스

여러 애그리거트가 필요한 기능 도메인 영역의 코드를 작성하다 보면, 한 애그리거트로 기능을 구현할 수 없을 때가 있다. 결제 금액 계산 로직을 생각해보자. 우선 구매하려는 상품의 가격이 필요하므로 상품 애그리거트가 필요하다. 또 상품 별로 몇 개를 구매할 것인지 알아야 하므로 주문 애그리거트가 필요하다. 또 할인 금액이나 비율, 제약 조건 등이 필요하므로 할인 애그리거트가 필요하고, 회원 등급에 따라 또 할인 등급이 나뉘어진다면 회원 애그리거트도 필요할 것이다. 해당 상황에서 실제 결제 금액을 계산하는 주체는 누구일까? 주문 애그리거트가 주체라 가정해보자. 그렇다면 의문이 생긴다. 결제 금액 계산 로직이 주문 애그리거트의 책임에 들어갈까? 예를 들어 특별 감사 세일로 전 품목에 대해 한 달간 2% 추가 ..

책 정리/도메인 주도 개발 시작하기

Chapter 6. 응용 서비스와 표현 영역

표현 영역과 응용 영역 도메인이 제 기능을 하려면 사용자와 도메인을 연결해주는 매개체가 필요하다. 표현 영역과 응용 영역이 사용자와 도메인을 연결해 주는 매개체 역할을 한다. 표현 영역은 사용자의 요청을 해석한다. 웹 브라우저는 요청 파라미터를 포함한 HTTP 요청을 표현 영역에 전달한다. 요청을 받은 표현 영역은 URL, 요청 파라미터, 쿠키, 헤더 등을 이용해서 사용자가 실행하고 싶은 기능을 판별하고 그 기능을 제공하는 응용 서비스를 실행한다. 실제 사용자가 원하는 기능을 제공하는 것은 응용 영역에 위치한 서비스다. 응용 서비스는 기능을 실행하는 데 필요한 입력 값을 메서드 인자로 받고 실행 결과를 리턴한다. 응용 서비스의 메서드가 요구하는 파라미터와 표현 영역이 사용자로부터 전달받은 데이터는 형식이..

책 정리/도메인 주도 개발 시작하기

Chapter 5. 스프링 데이터 JPA를 이용한 조회 기능

검색을 위한 스펙 검색 조건이 고정되어 있고, 단순하다면 특정 조건으로 조회하는 기능을 만들면 된다. public interface OrderDataDao { Optional findById(OrderNo id); List findByOrderer(String ordererId, Date fromDate, Date toDate); ... } 그런데 목록 조회와 같은 기능은 다양한 검색 조건을 조합해야할 때가 있다. 물론 필요한 조합마다 find 메서드를 만드는 것도 방법일 수는 있지만, 좋은 방법은 아니다. (조합이 증가할수록 정의해야할 find 메서드도 함께 증가하기 때문) 이렇게 검색 조건을 다양하게 조합해야 할 때 사용할 수 있는 것이 스펙(Specification)이다. 스펙은 애그리거트가 특정 ..

책 정리/도메인 주도 개발 시작하기

Chapter 4. 리포지터리와 모델 구현

매핑 구현 애그리거트 루트는 엔티티이므로 @Entity로 매핑 설정한다. 한 테이블에 엔티티와 밸류 데이터가 같이 있다면 밸류는 @Embeddable로 매핑 설정한다. 밸류 타입 프로퍼티는 @Embedded로 매핑 설정한다. @Entity @Table(name = "purchase_order") public class Order { @Embedded private Orderer orderer; ... } @Embeddable public class Orderer { // memberId에 정의된 칼럼 이름을 변경하기 위해 @AttributeOverride 사용 @Embedded @AttributeOverrides( @AttributeOverride(name = "id", column = @Column(n..

void_melody
'책 정리/도메인 주도 개발 시작하기' 카테고리의 글 목록