일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 알고리즘
- 도메인 주도 개발 시작하기
- CleanCode
- AWS RDS
- DDD
- MariaDB
- vue.js
- 인프런백기선
- AWS
- SQL쿡북
- 스프링부트와AWS로혼자구현하는웹서비스
- 클린코드
- 알고리즘분석
- 자바스터디
- mysql
- 이펙티브자바
- 혼공SQL
- java
- react
- 이펙티브 자바
- 기술면접
- 인프런김영한
- 네트워크
- 자바예외
- 자바
- 자료구조
- 인덱스
- jpa
- 이팩티브 자바
- aop
- Today
- Total
목록도메인 주도 개발 시작하기 (12)
기록이 힘이다.
단일 모델의 단점 식별자를 이용해서 애그리거트를 참조하는 방식을 사용하면 즉시 로딩과 같은 JPA 의 쿼리 관련 최적화 기능을 사용할 수 없다. 애그리거트 간의 연관을 ID가 아니라 직접 참조하는 방식으로 연결해도 고민거리가 생긴다. 이런 고민이 발생하는 이유는 시스템의 상태를 변경할 때와 조회할 때 단일 도메인 모델을 사용하기 때문이다. ORM 기법은 주문 상세 조회 화면처럼 여러 애그리거트에서 데이터를 가져와 출력하는 기능을 구현하기에는 고려할 게 많아서 구현을 복잡하게 만드는 원인이 된다. 구현 복잡도를 낮추기 위해, 상태 변경을 위한 모델과 조회를 위한 모델을 분리할 수 있다. https://www.youtube.com/watch?v=xf0kXMTFJm8 CQRS 상태 변경 범위와 상태 조회 범위..
시스템 간 강결합 문제 주문 도메인에서 환불을 진행하려고 할때 환불 기능을 제공하는 도메인 서비스를 통해 실행하게 된다. 보통 결제 시스템은 외부에 존재하므로 도메인 서비스에서 외부서비스를 호출한다. 이때 여러 문제가 발생할수 있다. 첫번째로 외부 서비스가 정상이 아닐 경우 트랜잭션 처리를 어떻게 해야하는가? 환불기능 실행중 예외 발생시 롤백할지 커밋할지 애매하다. 두번째로 외부 시스템의 응답이 길어질 경우의 성능 문제이다. 환불 처리 기능이 오래걸릴수록 주문 취소 기능 또한 대기 시간이 증가한다. 즉, 외부 서비스 성능에 직접적인 영향을 받는다. 추가적인 문제로 설계상 문제가 나타날 수 있다. 주문을 표현하는 도메인에 결제 도메인의 환불 로직이 뒤섞이게 된다. 지금 까지 언급한 문제가 발생하는 이유는 ..
도메인 모델과 경계 처음 도메인 모델을 만들 때 빠지기 쉬운 함정이 도메인을 완벽하게 표현하는 단일 모델을 만드는 시도를 하는 것이다. 그런데 1장에서 말한 것처럼 한 도메인은 다시 여러 하위 도메인으로 구분되기 때문에 한 개의 모델로 여러 하위 도메인을 모두 표현하려고 시도하면 오히려 모든 하위 도메인에 맞지 않는 모델을 만들게 된다. 논리적으로 같은 존재처럼 보이지만 하위 도메인에 따라 다른 용어를 사용하는 경우도 있다. 하위 도메인마다 사용하는 용어가 다르기 때문에 올바른 도메인 모델을 개발하려면 하위 도메인마다 모델을 만들어야 한다. 모델은 특정한 컨텍스트(문맥) 하에서 완전한 의미를 갖는다. 같은 제품이라도 카탈로그 컨텍스트와 재고 컨텍스트에서 의미가 서로 다른다. 이렇게 구분되는 경계를 갖는 ..
애그리거트와 트랜잭션 두 스레드는 각각 트랜잭션을 커밋할 때 수정한 내용을 DBMS에 반영한다. 즉, 배송 상태로 바뀌고 배송지 정보도 바뀌게 된다. 이 순서의 문제점은 운영자는 기존 배송지 정보를 이용해서 배송 상태로 변경했는데 그 사이 고객은 배송지 정보를 변경했다는 점이다. 즉, 애그리거트의 일관성이 깨지는 것이다. 이런 문제가 발생하지 않도록 하려면 두 가지 중 하나를 해야 한다. 운영자가 배송지 정보를 조회하고 상태를 변경하는 동안 고객이 애그리거트를 수정하지 못하게 막는다. 운영자가 배송지 정보를 조회한 이후에 고객이 정보를 변경하면 운영자가 에그리거트를 다시 조회한 뒤 수정하도록 한다. 애그리거트에 대해 사용할 수 있는 대표적인 트랜잭션 처리 방식에는 선점(Pressimistic) 잠금과 비..
여러 애그리거트가 필요한 기능 도메인 영역의 코드를 작성하다 보면 한 애그리거트로 기능을 구현할 수 없을 때가 있다. 대표적인 예가 결제 금액 계산 로직이다. 실제 결제 금액을 계산할 때는 다음과 같은 내용이 필요하다. 상품 애그리거트 : 구매하는 상품의 가격이 필요하다. 또한 상품에 따라 배송비가 추가되기도 한다. 주문 애그리거트 : 상품별로 구매 개수가 필요하다. 할인 쿠폰 애그리거트 : 쿠폰별로 지정한 할인 금액이나 비율에 따라 주문 총금액을 할인한다. 회원 애그리거트 : 회원 등급에 따라 추가 할인이 가능하다 이 상황에서 실제 금액을 계산해야 하는 주체는 어떤 애그리거트일까? 이 할인 금액을 구하는 것은 누구 책임일까? 한 애그리거트에 넣기에 애매한 도메인 기능을 특정 애그리거트에서 억지로 구현하..
표현 영역과 응용 영역 표현 영역의 코드는 다음과 같이 폼에 입력한 요청 파라미터 값을 사용해서 응용 서비스가 요구하는 객체를 생성한 뒤, 응용 서비스의 메서드를 호출한다. @PostMapping("/member/join") public ModelAndView join(HttpServletRequest request){ String email = request.getParameter("email"); String password = request.getParameter("password"); //사용자 요청을 응용 서비스에 맞게 변환 JoinRequest joinReq = new JoinReqeust(email, password); //변환한 객체(데이터)를 이용해서 응용 서비스 실행 joinServic..
CORS는 명령 모델과 조회 모델을 분리하는 패턴이다. 명령 모델은 상태를 변경하는 기능을 구현(회원가입, 암호 변경, 주문 취소)할 때 사용하고 조회 모델은 데이터를 조회하는 기능을 구현(주문 목록, 주문 상세처럼 데이터를 보여주는 기능)할 때 사용한다. 이 장에서 살표볼 구현 방법은 조회 모델을 구현할 때 주로 사용한다. 검색을 위한 스펙 검색 조건을 다양하게 조합해야 할 때 사용할 수 있는 것이 스펙이다. 스펙은 애그리거트가 특정 조건을 충족하는지를 검사할 때 사용하는 인터페이스다. public interface Specification { public boolean isSatisfiedBy(T agg); } 스펙을 리포지터리에 사용하면 egg는 애그리거트 루트가 되고, 스펙을 DAO에 사용하면 a..
JPA를 이용한 리포지터리 구현 리포지터리 기본 기능 구현 -ID로 애그리거트 조회하기 -애그리거트 저장하기 public interface OrderRepository{ Order findById(OrderNo no); void save(Order order); } @Repository public class JpaOrderRepository implements OrderRepository { @PersistenceContext private EntityManager entityManager; @Override public Order findById(OrderNo id) { return entityManager.find(Order.class, id); } @Override public void save(..