이 포스트는 📔 도메인 주도 개발 시작하기 책을 읽고 공부한 내용을 정리한 포스트입니다.
도메인 영역을 작성할 때 여러 애그리거트의 기능을 통합하여 기능을 구현해야 하는 경우가 발생한다. 이러한 상황에서 기능의 책임을 어떤 애그리거트에게 맡겨야 할까? 애그리거트 루트가 모든 책임을 담당하는 것이 옳을까?
한 애그리거트에 넣기 애매한 도메인 기능을 억지로 특정 애그리거트에 책임을 맡기고 구현하는 것은 옳지 않다.
억지로 구현하게 된다면 애그리거트는 자신의 책임 범위를 넘어서는 기능의 구현을 하게 되므로 외부 의존이 높아지고 코드가 복잡해진다.
그렇다면 이러한 문제는 어떻게 해소할까? 도메인 기능을 별도 서비스로 구현함으로 써 해결할 수 있다.
도메인 서비스는 도메인 영역에 위치한 도메인 로직을 표현하기 위해 아래와 같은 상황에서 사용한다.
도메인 서비스를 이용한 도메인 개념의 명시는 상태 없이 오직 로직만을 구현한다는 점에서 도메인 영역의 애그리거트나 밸류와 같은 구성요소와의 차이가 존재한다.
계산 로직을 구현한 도메인 서비스를 사용하는 주체는 애그리거트가 될 수도 있고 응용 서비스가 될 수도 있다.
사용 주체가 애그리거트인 경우 응용 서비스에서 애그리거트 객체에 도메인 서비스를 전달하는 책임을 갖는다.
사용 주체가 응용 서비스인 경우 도메인 서비스의 기능을 실행 할 때 애그리거트를 전달함으로써 도메인 서비스를 구현할 수 있다.
도메인 서비스는 도메인 로직을 수행하기 위해 존재하는 서비스로 응용 로직을 수행하지 않기에 트랜잭션 처리를 도메인 서비스에서 하는 방식은 적합하지 않은 방식이다.
외부 시스템을 활용하는 도메인의 기능의 경우 외부 시스템을 연동받는 도메인 서비스에서 구현이 가능하다.
이때 도메인 서비스에서 활용하는 외부 시스템은 인프라스트럭처 영역에 위치해 기능을 구현할 수 있어야 한다.
위와 같이 구현된 도메인 서비스의 패키지 위치는 어디일까?
도메인 서비스는 도메인 로직을 표현하기 위해 생성된 서비스이므로 도메인 패키지에 엔티티와 벨류와 함께 위치하는 것이 옳다고 본다.
만약 도메인 서비스의 로직이 고정되어 있지 않다면 인터페이스를 구현하고 이를 상속하는 방식으로 구현 클래스를 활용하는 방식으로 도메인 서비스를 구현하는 것도 고려해 볼 수 있다.