728x90
반응형
목차
도메인 서비스
도메인 서비스를 사용하는 상황
- 계산 로직 : 여러 애그리거트가 필요한 계산 로직이나, 한 애그리거트에 넣기에는 다소 복잡한 계산 로직
- 외부 연동 시스템이 필요한 도메인 로직 : 구현하기 위해 타 시스템을 사용해야 하는 도메인 로직
계산 로직과 도메인 서비스
- 할인 규칙 같이 한 애그리거트에 넣기 애매한 도메인 개념 구현시 도메인 서비스를 이용해 도메인 개념을 명시적으로 드러내면 됨
- 도메인영역의 애그리거트, 밸류와 같은 구성요소 vs 도메인 서비스
- 도메인 서비스는 상태없이 로직만 구현
- 도메인 서비스에 필요한 상태는 다른 방법으로 전달받음
public class DiscountCalculationService {
public Money calcutationDiscountAmounts(List<OrderLine> orderLines,
List<Coupon> coupons,
MemberGrade grade) {
Money couponDiscount = coupons.stream()
.map(coupon -> calculateDiscount(coupon))
.reduce(Money(0), (v1, v2) -> v1.add(v2));
Money membershipDiscount = calculateDiscount(orderer.getMember().getGrade());
return couponDiscount.add(membershipDiscount);
}
private Money calculateDiscount(Coupon coupon) {
}
private Money calculateDiscount(MemberGrade grade) {
}
}
- 할인 계산 서비스 사용 주체는 애그리거트 일 수도 있고 응용서비스일 수도 있음
public class Order {
public void calculateAmounts(DiscountCalculationService disCalSvc, MemberGrade grade) {
Money totalAmounts = getTotalAmounts();
Money discountAmounts disCalSvc.calcutationDiscountAmounts(this.orderLines, this.coupons, grade);
this.paymentAmounts = totalAmounts.minus(discountAmounts);
}
}
- 애그리거트 객체에 도메인 서비스를 전달하는 것은 응용 서비스의 책임
- 도메인 객체에 애그리거트 주입하지 않는다.
- 도메인 객체는 필드로 구성된 데이터와 메서드를 이용해 개념적으로 하나인 모델을 표현함
- 모델 내 데이터 필드는 데이터를 담는 중요한 구성요소인데 discountCalculationService는
Order객체에서 DB에 데이터를 저장하는데 사용하는 필드가 아님 - Order가 제공하는 모든 기능에서 discountCalculationService를 필요로하지 않기 때문에
애그리거트에 도메인 서비스 객체를 주입할 이유가 없음
- 계좌 이체는 두 계좌 애그리거트가 관여함 (출금, 입금)
- 응용서비스는 두 Account 애그리거트를 구한 후 해당 도메인 영역의 TransferService를 이용해 계좌이체 도메인 기능을 실행
- 도메인서비스는 도메인 로직을 수행하고 응용로직수행은 하지 않음
트랜잭션처리는 응용로직이므로 응용서비스에서 처리
☝🏼도메인 서비스인지 응용서비스인지 체크 하는 방법
계좌이체는 계좌 애그리거트의 상태를 변경하고 결제금액로직은 주문 애그리거트의 주문금액을 계산한다.
이 두 로직은 애그리거트를 변경하고 값을 계산하기 때문에 도메인 로직이다.
도메인 로직이면서 한 애그리거트에 넣기 적합하지 않기 때문에 도메인 서비스로 구현한다.
외부 시스템 연동과 도메인 서비스
- 외부시스템이나 타 도메인과의 연동 기능도 도메인 서비스가 될 수 있음
- 설문조사 시스템에서 설문조사를 생성할 때 사용자가 생성 권한이 있는지 확인하는 역할
- 도메인로직으로 볼 수 있고 이 로직은 도메인 서비스로 표현 가능
- 도메인 로직 관점에서 인터페이스를 작성함
- 응용서비스는 도메인서비스를 이용해서 생성 권한을 검사함
- SurveyPermissionChecker 인터페이스를 구현한 클래스는 인프라스트럭처 영역에 위치
도메인 서비스의 패키지 위치
- 도메인 서비스는 도메인 로직을 표현하기 때문에 다른 도메인 구성요소와 동일한 패키지에 위치
- 명시적으로 구분을 원한다면 domain 패키지 밑에 domain.model, domain.service, domain.repository와 같이 하위 패키지로 구분해서 위치시켜도 됨
인터페이스와 클래스
- 도메인 서비스의 로직이 고정되어있지 않으면 도메인 서비스 자체를 인터페이스로 구현하고 이를 구현한 클래스를 둘 수 있음
- 도메인 서비스의 구현이 특정 구현 기술에 의존하거나 외부 시스템의 API를 실행하면 도메인 영역의 도메인 서비스는 인터페이스로 추상화 해야 함.
728x90
반응형
'책리뷰 > 도메인 주도 개발 시작하기(DDD핵심 개념 정리부터 구현까지)' 카테고리의 다른 글
도메인 주도 개발(DDD) 도메인 모델과 바운디드 컨텍스트 (0) | 2022.05.26 |
---|---|
도메인 주도 개발(DDD) 애그리거트 트랜잭션 관리 (0) | 2022.05.24 |
도메인 주도 개발 (DDD) 시작하기 응용서비스와 표현영역 (0) | 2022.05.19 |
도메인 주도 설계(DDD) 스프링데이터 JPA를 이용한 조회 (0) | 2022.05.17 |
도메인 주도 개발(DDD) 리포지터리와 모델 구현 (0) | 2022.05.13 |