일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- S3
- 백준 10815 # 백준 Java
- @Valid
- wss 연결 실패
- 소셜 로그인
- 스프링부트
- 도메인 주도 개발
- springboot
- 관점 지향 프로그래밍
- 패러다임 불일치
- spring boot
- CustomException
- oauth2.0
- 구글 로그인
- validation
- spring websocket nginx 설정
- presigned url
- jwt
- 자바 orm
- logout
- 개발 프로젝트
- 이미지 업로드
- GoormIDE
- 예외 처리
- Flask
- OpenAI API
- fastapi
- session
- AWS
- ec2 nginx websocket reverse proxy
- Today
- Total
목록책/DDD: 도메인 주도 개발 (11)
개발세발은 안되요

11.1 단일 모델의 단점 조회 기능을 구현하려면 여러 애그리거트에서 데이터를 가져와야 한다. 조회 화면 특성상 조회 속도가 빠를수록 좋은데 여러 애그리거트의 데이터가 필요하면 구현 방법을 고민해야 한다. 식별자를 이용해서 애그리거트를 참조하는 방식을 사용하면 즉시 로딩 방식과 같은 JPA의 쿼리 관련 기능을 사용할 수 없고, 이는 한번의 SELECT 쿼리로 조회 화면에 필요한 데이터를 읽어올 수 없어 조회 성능에 문제가 생길 수 있다는 것을 의미한다. 애그리거트 간 연관을 직접 참조하는 방식으로 연결해도 여러 고민거리가 생긴다. 이런 고민이 발생하는 이유는 시스템 상태를 변경할 때와 조회할 때 단일 도메인 모델을 사용하기 때문이다. 객체 지향으로 도메인 모델을 구현할 때 주로 사용하는 ORM 기법은 도..

10.1 시스템 간 강결합 문제 시스템 간의 강결합(high coupling)에 의해 발생할 수 있는 문제들은 다음과 같다. - 외부 시스템이 정상이 아닐 경우 트랜잭션 처리를 어떻게 해야 할지 애매하다. - 외부 서비스의 성능에 직접 영향을 받는다. - 도메인 객체에 서로 다른 로직이 섞인다. 위의 문제들은 이벤트를 이용하여 완화시킬 수 있다. 예를 들어 쇼핑몰엣거 구매를 취소했을 때 환불을 처리하는 상황이 있을 수 있다. 환불 기능을 실행하는 주체는 주문 도메인 에티티가 될 수 있고, 또는 응용 서비스에서 환불 기능을 실행할 수도 있다. 이때 보통 결제 시스템은 외부에 존재하기 때문에 응용 시스템은 외부에 있는 결제 시스템이 제공하는 환불 서비스를 제공할 수 있을 것이다. 이때 발생할 수 있는 문제들..

9.1 도메인 모델과 경계 모델은 특정한 컨텍스트(문맥) 하에서 완전한 의미를 갖는다. 각 모델은 경계를 가지도록 해서 섞이지 않도록 해야 하는데, 여러 하위 도메인 모델이 섞이기 시작하면 각 하위 도메인별로 다르게 발전하는 요구사항을 모델에 반영하기 어려워진다. 이렇게 구분되는 경계를 갖는 컨텍스트를 DDD 에서는 바운디드 컨텍스트(Bounded Context) 라고 한다. 처음 도메인 모델을 만들 때 주의해야 하는 것은 한 개의 모델로 여러 하위 도메인을 모두 표현하려고 하면 안된다는 것이다. 이렇게 만들 경우 모든 하위 도메인에 맞지 않는 모델을 만들게 될 수 있다. 또 논리적으로 같은 존재처럼 보이지만 하위 도메인에 따라 다른 용어를 사용하는 경우도 있다. 따라서 올바른 도메인 모델을 설계하기 위..

8.1 애그리거트와 트랜잭션 한 애그리거트를 두 사용자가 동시에 변경할 때 트랜잭션과 함께 애그리거트를 위한 추가적인 트랜잭션 처리 기법이 필요하다. 대표적인 트랜잭션 처리 방식으로는 선점 잠금과 비선점 잠금의 두 가지 방식이 있다. 아래의 그림은 운영자와 고객이 동시에 한 주문 애그리거트를 수정하는 과정을 보여준다. 트랜잭션마다 리포지터리는 새로운 애그리거트 객체를 생성하기에 운영자 스레드와 고객 스레드는 같은 주문 애그리거트를 나타내는 다른 객체를 구하게 된다. 물리적으로 서로 다른 애그리거트 객체를 사용하기 때문에 각 객체의 상태 변경이 서로에게 영향을 주지 않는다. 그리고 두 스레드는 각각 트랜잭션을 커밋할 때 수정한 내용을 DB에 반영한다. 이때 배송 상태와 배송지 정보가 바뀌는데, 애그리거트의..

7.1 여러 애그리거트가 필요한 기능 도메인 영역의 코드를 구현할 때 한 애그리거트로 기능을 구현할 수 없을 때가 있다. 이 때 해당 기능을 구현해야 하는 주체가 되는 애그리거트가 무엇인지를 고민해볼 필요가 있다. 이 경우 한 애그리거트에 넣기 애매한 도메인 기능을 억지로 몰아넣게 되면 코드의 길이가 길어지고 외부에 대한 의존이 높아지는 등의 문제가 발생할 수 있다. 따라서 도메인 기능을 별도 서비스로 구현하는 방법을 생각해볼 수 있다. 도메인 영역의 코드를 작성하다보면 한 애그리거트로 기능을 구현할 수 없을 때가 있다. 예를 들어 결제 금액 예상 로직이 있을 수 있다. - 상품 애그리거트 : 구매하느 상품의 가격 필요, 배송비 추가되기도 함. - 주문 애그리거트 : 상품별 구매 개수 필요 - 회원 애그..
6.1 표현 영역과 응용 영역 도메인이 제 기능을 하기 위해서는 사용자와 도메인을 연결해주는 매개체가 필요하고, 이 역할을 해주는 것이 응용 영역과 표현 영역이다. 표현 영역 사용자의 요청을 해석한다. 사용자가 웹 브라우저에서 폼에 ID와 암호를 입력한 뒤에 전송 버튼을 클릭하면 요청 파라미터를 포함한 HTTP 요청을 포현 영역에 전달한다. 요청을 받은 표현 영역은 URL, 요청 파라미터 쿠키, 헤더 등을 이용해서 사용자가 실행하고 싶은 기능을 판별하고 그 기능을 제공하는 응용 서비스를 실행한다. 응용 영역 실제 사용자가 원하는 기능을 제공하는 것은 응용 영역에 위치한 서비스이다. 응용 서비스는 기능을 실행하는 데 필요한 입력 값을 메서드 인자로 받고 실행 결과를 리턴한다. 응용 서비스의 메서드가 요구하..

5.1 시작에 앞서 CORS 란 명령(command) 모델과 조회(query) 모델을 분리하는 패턴이다. 명령 모델은 상태를 변경하는 기능을 구현할 때 사용하고 조회 모델은 조회하는 기능을 구현할 때 주로 사용한다. 이 장에서 사용하는 예제 코드는 리포지터리(도메인 모델에 속한)와 DAO(데이터 접근을 의미하는) 라는 이름을 혼용하여 사용한다. 5.2 검색을 위한 스펙 스펙(specfiaction) 은 애그리거트가 특정 조건을 충족하는지를 검사할 때 사용하는 인터페이스로, 검색 조건을 다양하게 조합해야 할 때 사용한다. 스펙 인터페이스는 다음과 같이 정의한다. public interface Specification{ public boolean isSatisfiedBy(T aff); // 검사 대상 객체가..
4.1 JPA를 이용한 리포지터리 구현 애그리거트를 어떤 저장소에 저장하느냐에 따라 리포지터리를 구현하는 방법이 다르다. 이 절에서는 자바의 ORM 표준인 JPA를 이용해서 리포지터리와 애그리거트를 구현하는 방법에 대해 알아본다. 4.1.1 모듈 위치 리포지터리 인터페이스는 애그리거트와 같이 도메인 영역에 속하고, 리포지터리를 구현한 클래스는 인프라스트럭처 영역에 속한다. 가능하면 리포지터리 구현 클래스를 인프라스트럭처 영역에 위치시켜서 인프라스트럭처에 대한 의존을 낮춰야 한다. 4.1.2 리포지터리 기본 기능 구현 리포지터리가 제공하는 기본 기능은 다음 두가지가 있다. 1. ID로 애그리거트 조회 2. 애그리거트 저장 삭제 기능의 경우, 삭제 요구사항이 있더라도 실제로 삭제하는 경우는 많지 않다. 관리..