목록Book Lounge/도메인 주도 개발 시작하기 (10)
고딩왕 코범석
Index 시스템 간 강결합 문제 이벤트 개요 이벤트 관련 구성요소 이벤트의 구성 이벤트 용도 이벤트 장점 이벤트, 핸들러, 디스패처 구현 이벤트 클래스 Events 클래스와 ApplicationEventPublisher 이벤트 발생과 이벤트 핸들러 흐름 정리 동기 이벤트 처리 문제 비동기 이벤트 처리 로컬 핸들러 비동기 실행 메시징 시스템을 이용한 비동기 구현 이벤트 저장소를 이용한 비동기 처리 이벤트 적용 시 추가 고려 사항 이벤트 처리와 DB 트랜잭션 고려 시스템 간 강결합 문제 쇼핑몰에서 환불 로직을 구현한다 가정할 때, 다음과 같은 방법이 있다. 도메인 객체에서 환불 기능을 제공하는 도메인 서비스를 파라미터로 받아 도메인의 상태를 변경 후 도메인 서비스를 실행 응용 서비스 자체에서 환불 기능 실..
Index 도메인 모델과 경계 바운디드 컨텍스트 바운디드 컨텍스트 구현 바운디드 컨텍스트 간 통합 바운디드 컨텍스트 간 관계 도메인 모델과 경계 한 개의 모델로 여러 하위 도메인을 모두 표현하려 시도하면 모든 하위 도메인에 맞지 않는 모델을 만들게 된다. 예를 들어, 카탈로그에서의 상품과 재고 관리에서의 상품, 주문 상품, 배송에서의 상품들은 모두 같은 상품이지만 실제 의미하는 것이 다르다. 카탈로그에서의 상품은 상품 제목, 내용과 같은 정보를 의미하고 재고 관리에서의 상품은 상품 갯수가 주된 정보이다. 여러 하위 도메인의 모델이 얽히기 시작하면 하위 도메인 별로 다르게 발전하는 요구사항을 모델에 반영하기 어려워진다. 이러한 이유로 한 개의 모델로 모든 하위 모델을 표현하려는 시도는 좋지 않다. 모델은 ..
Index 애그리거트와 트랜잭션 선점 잠금 선점 잠금과 교착상태 비선점 잠금 강제 버전 증가 오프라인 선점 잠금 오프라인 선점 잠금을 위한 LockManager 인터페이스와 관련 클래스 DB를 이용한 LockManager 구현 애그리거트와 트랜잭션 개념적으로 같은 애그리거트지만 물리적으로 다른 애그리거트 객체를 사용할 때 데이터의 일관성이 깨질 수 있다. 예를 들어 운영자가 상품을 배송 상태로 변경하는 요청, 고객의 배송지 요청이 동시 접근했을 때를 가정해본다. 운영자가 배송 상태를 변경할 때 고객의 배송지 변경 기능을 막아야 일관성이 지켜진다. 일관성이 깨지지 않도록 둘 중 하나의 방법을 선택해야한다. 운영자가 배송지 정보를 조회하고 상태를 변경하는 동안, 고객이 애그리거트를 수정하지 못하게 막는다. ..
Index 여러 애그리거트가 필요한 기능 도메인 서비스 계산 로직과 도메인 서비스 외부 시스템 연동과 도메인 서비스 도메인 서비스의 패키지 위치 도메인 서비스의 인터페이스와 클래스 여러 애그리거트가 필요한 기능 여러 애그리거트가 필요한 기능이 있을 때 특정 도메인에 로직을 몰아넣게 되면 다음과 같은 문제점이 발생한다. 코드가 길어지고 외부 의존도가 높아진다. 애그리거트의 범위를 넘어서는 도메인 개념이 애그리거트에 숨어 명시적으로 드러나지 않는다. 이 경우 도메인 기능을 별도의 서비스로 구현하는 방법이 있다. 위로 도메인 서비스 도메인 서비스는 도메인 영역에 위치한 도메인 로직을 표현할 때 사용한다. 주로 다음과 같은 상황에 사용한다. 계산 로직 : 여러 애그리거트가 필요한 계산 로직이거나 한 애그리거트에..
Index 표현 영역과 응용 영역 표현 영역의 역할 응용 서비스의 역할 도메인 로직 넣지 않기 응용 서비스의 구현 응용 서비스의 크기 응용 서비스의 인터페이스와 클래스 메서드 파라미터와 값 리턴 표현 영역에 의존하지 않기 트랜잭션 처리 표현 영역 표현 영역의 책임 값 검증 권한 검사 권한 검사가 수행되어야 하는 곳? 조회 전용 기능과 응용 서비스 표현 영역과 응용 영역 표현 영역의 역할 URL, 요청 파라미터, 쿠키, 헤더 등을 이용해 사용자가 실행하고 싶은 기능을 판별해 해당 기능을 제공하는 응용 서비스를 실행하는 역할 응용 서비스를 실행하기 위해 응용 서비스가 요구하는 형식으로 사용자 요청을 변경 실행 결과를 사용자에게 알맞은 형식으로 응답 HTML, JSON … 응용 영역은 표현 영역에 의존하지 않..
Index CQRS 검색을 위한 스펙 스프링 데이터 JPA를 이용한 스펙 구현 정렬 지정 페이징 처리하기 @Subselect CQRS 앞에서 봤던 애그리거트, 리포지터리, 엔티티와 같은 모델은 상태를 변경할 때 주로 사용한다. 조회용 모델과 상태 변경의 모델은 다르기 때문에 만약 조회를 위해 엔티티에 연관 관계와 같은 설정이 변경될 수 있다면 가급적 조회 모델을 따로 만드는게 좋다. 위로 검색을 위한 스펙 검색 조건을 조합해야 할 경우 조건별 find..()를 만들기 보다 애그리거트가 특정 조건을 충족하는지 검사할 때 사용하는 Specification 인터페이스를 만들어서 사용하는게 좋다. public interface Specification { boolean isSatisfiedBy(T agg); }..
Index JPA를 이용한 리포지터리 구현 스프링 데이터 JPA를 이용한 리포지터리 구현 매핑 구현 엔티티와 기본 밸류 매핑 구현 기본 생성자 필드 접근 방식 사용 AttributeConverter를 이용한 밸류 매핑 처리 밸류 컬렉션 : 별도 테이블 매핑 밸류 컬렉션 : 한 개 컬럼 매핑 밸류를 이용한 ID 매핑 별도 테이블에 저장하는 밸류 매핑 밸류 컬렉션을 @Entity로 매핑하기 ID참조와 조인 테이블을 이용한 단방향 M:N 매핑 매핑 부록 EmbeddedId 애그리거트 로딩 전략 애그리거트의 영속성 전파 식별자 생성 기능 도메인 구현과 DIP JPA를 이용한 리포지터리 구현 모듈 위치와 기본 기능 구현 Repository 인터페이스는 애그리거트와 같이 도메인 영역에 속한다. 구현체는 Infras..
Index 애그리거트 애그리거트 루트 리포지터리와 애그리거트 ID를 이용한 애그리거트 참조 애그리거트 간 집합 연관 애그리거트를 팩토리로 사용하기 애그리거트 애그리거트는 관련된 모델들을 하나로 모았기 때문에 한 애그리거트에 속한 객체는 유사하거나 동일한 라이프사이클을 갖게 된다. 애그리거트는 경계를 갖게 되며, 한 애그리거트에 속한 객체는 다른 애그리거트에 속하지 않는다. 예를 들어, 주문 애그리거트에서 배송지 혹은 상품 갯수를 변경할 수 있지만 회원의 정보를 변경할 수 없다. 도메인 규칙에 따라 함께 생성되는 구성요소는 한 애그리거트에 속할 가능성이 높다. 하지만 ‘A가 B를 갖는다’ 라는 요구사항이 있다고 해서 A와 B가 반드시 한 애그리거트에 속하는 것은 아니다. 예를 들어, 하나의 상품이 등록되어..