- 한 애그리거트로 기능을 구현할 수 없을 때
- 도메인 영역에 위치한 도메인 로직을 표현할 때 사용
- 도메인 서비스를 이용해서 도메인 개념을 명시적으로 드러낸다.
- 응용 영역의 서비스가 응용 로직을 다룬다면 도메인 서비스를 도메인 로직을 다룬다.
도메인 서비스는 도메인의 의미가 들어나는 용어를 타입과 메서드 이름으로 갖는다.
class DiscountCalculationService {
fun calculateDiscountAmounts( orderLines: List<OrderLine>, coupons: List<coupons>, grade: MemberGrade) {
val couponDiscount = coupons.stream()
.map {coupon -> calculateDiscount(coupon)}
.reduce {Money(0), (v1, v2) -> v1.add(v2)}
val membershipDiscount = calculateDiscount(orderer.getMember().getGrade())
return couponDiscount.add(membershipDiscount)
}
private fun calculateDiscount(coupon: Coupon): Money {
// ...
}
private fun calculateDiscount(grade: MemberGrade): Money {
// ...
}
}
애그리거트 객체에 도메인 서비스를 전달하는 것은 응용 서비스 책임이다.
- 외부 시스템이나 타 도메인과의 연동 기능도 도메인 서비스가 될 수 있다.
- 도메인 서비스는 도메인 로직을 표현하므로 도메인 서비스의 위치는 다른 도메인 구형요소와 동일한 패키지에 위치한다.
- 도메인 서비스의 로직이 고정되어 있지 않은 경우 도메인 서비스 자체를 인터페이스로 구현
- 도메인 로직을 외부 시스템이나 별도 엔진을 이용해서 구현할 때 분리