도메인 주도 개발 시작하기 (7) - 도메인 서비스

Jaewoo Ha·2022년 12월 11일
0

7.1 여러 애그리거트가 필요한 기능

  • 한 애그리거트로 기능을 구현할 수 없을 때

주의할 점

  • 한 애그리거트에 넣기 애매한 도메인 기능을 특정 애그리거트에 구현하기 되면 책임 범윌르 넘엇는 기능을 구현하게 된다.

해결 방법

  • 도메인 기능을 별도 서비스로 구현

7.2 도메인 서비스

  • 도메인 영역에 위치한 도메인 로직을 표현할 때 사용

7.2.1 계산 로직과 도메인 서비스

  • 도메인 서비스를 이용해서 도메인 개념을 명시적으로 드러낸다.
  • 응용 영역의 서비스가 응용 로직을 다룬다면 도메인 서비스를 도메인 로직을 다룬다.

도메인 서비스는 도메인의 의미가 들어나는 용어를 타입과 메서드 이름으로 갖는다.

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 {
        // ...
    }
}

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

애그리거트 객체에 도메인 서비스 전달 방법

  • 응용 서비스에서 파라미터를 통해 전달한다.
  • 도메인 서비스의 기능을 실행할 때 애그리거트를 전달한다.

7.2.2 외부 시스템 연동과 도메인 서비스

  • 외부 시스템이나 타 도메인과의 연동 기능도 도메인 서비스가 될 수 있다.

중요한 점

  • 도메인 로직 관점에서 인터페이스를 작성한다.
  • 응용 서비스는 도메인 서비스를 이용하여 생성 권한을 검사한다.
  • 구현한 인터페이스는 인프라스트럭처 영역에 위치해 연동을 포함한 권한 검사 기능을 구현한다.

7.2.3 도메인 서비스의 패키지 위치

  • 도메인 서비스는 도메인 로직을 표현하므로 도메인 서비스의 위치는 다른 도메인 구형요소와 동일한 패키지에 위치한다.

7.2.4 도메인 서비스의 인터페이스와 클래스

  • 도메인 서비스의 로직이 고정되어 있지 않은 경우 도메인 서비스 자체를 인터페이스로 구현
  • 도메인 로직을 외부 시스템이나 별도 엔진을 이용해서 구현할 때 분리

장점

  • 도메인 영역이 특정 구현에 종속되는 것을 방지
  • 도메인 영역에 대한 테스트가 간편해짐
profile
내일의 코드는 더 안전하고 깔끔하게

0개의 댓글