#07장 도메인 서비스

최범균 저「DDD START!, 2016」를 읽고 정리하였습니다.

7장 도메인 서비스

요약

  • 한 애그리거트로 기능을 구현할 수 없을 때 도메인 서비스를 사용하자.

  • 응용 서비스인지 도메인 서비스 구별법

    • 로직이 애그리거트의 상태를 변경하거나 애그리거트의 상태 값을 계산하는지 검사해 보면 된다.

  • 책에선, 결제 금액 계산을 사례로 든다.

    • 상품, 주문, 할인 쿠폰, 회원 애그리거트가 연결되기 때문에 사례로 든듯 한다.

아래 코드를 사용해서, 20% 할인 행사를 하는 이벤트가 있을때, 주문 애그리거트와 관련 없는 할인 로직을 설정해줘야한다.

// BEFORE
// 모든 애그리거트가 주문 애그리거트에 우겨 넣어진 코드 
public class Order {
    private Orderer orderer;
    private List<OrderLine> orderLines;
    private List<Coupon> usedCoupons;
    private Money calculatePayAmounts() {
        Money totalAmounts = calculateTotalAmounts();
        Money discount =
            coupons.stream()
            .map(coupon -> calculateDiscount(coupon))
            .reduce(Money(0), (vl, v2) -> vl.add(v2));
        Money membershipDiscount =
            calculateDiscount(orderer.getMember().getGrade());
        return totalAmounts.minus(discount).minus(membershipDiscount);
    }
    private Money calculateDiscount(Coupon coupon) {
        // ...
    }
    private Money calculateDiscount(MemberGrade grade) {
        // ...
    }
}

이 문제를 해결하기 위해 도메인 서비스를 이용하자.

도메인 서비스가 다른 구성요소 (애그리거트나 밸류) 와의 다른 점은 상태 없이 로직만 구현한다는 점이다. (상태가 필요할때는, 전달받아 사용한다)

구현시, 도메인 용어를 타입과 메서드 이름으로 갖는다. (의미전달 UP)

도메인 서비스를 이용하면 다음과 같다.

애그리거트 객체(=Order)에 도메인 서비스(=DiscountCalculationService)를 전달하는 것은 응용 서비스 책임이다.

Last updated