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

도메인 영역의 코드를 작성하다 보면, 한 애그리거트로 기능을 구현할 수 없을 때가 있다. 대표적인 예가 상품, 주문, 할인 쿠폰, 회원 애그리거트들이 관여하는 결제 금액 계산 로직이다.

 

이 상황에서는 어떤 애그리거트가 주체인지 쉽게 판단할 수 없다. 어찌어찌 한 도메인 안에 욱여 넣더라도, 자신의 책임 범위를 넘어서는 기능을 구현하기 때문에 다음의 단점이 존재한다. 1) 코드가 길어지고 2) 외부에 대한 의존이 높아지게 되며 3) 코드가 복잡하여 수정이 어렵다. 4) 게다가 애그리거트 범위를 넘어서는 도메인 개념이 애그리거트에 숨어들어 명시적으로 드러나지 않게 된다.

 

이에 대한 해결 방법으로는 별도 서비스로 구현하는 것이다.

 

2. 도메인 서비스

도메인 서비스는 도메인 영역에 위치한 도메인 로직을 표현할 때 사용한다. 주로 여러 애그리거트가 필요한 계산이나 외부 시스템 연동이 필요한 경우에 사용한다.

 

계산 로직과 도메인 서비스

결제 금액 계산처럼 한 애그리거트에 넣기 애매한 도메인 기능은, 도메인 서비스를 이용해서 도메인 개념을 명시적으로 드러낼 수 있다.

 

응용 서비스 vs 도메인 서비스

응용 서비스는 도메인 로직 없이, 그저 표현 영역과 도메인 영역을 연결하는 창구 역할을 수행한다. 따라서 응용 서비스는 애그리거트나 도메인 서비스의 로직을 실행하기만 할 뿐이다.

반면 도메인 서비스는 애그리거트의 상태를 변경하거나 상태 값을 계산하는 도메인 로직이 존재한다. 트랜잭션 처리와 같은 로직은 응용 로직이므로 응용 서비스에서 처리한다.

 

도메인 서비스 vs 애그리거트가 가진 기능들

애그리거트는 도메인 로직 뿐만 아니라 관련된 필드를 가지고 있다. 반면 도메인 서비스는 상태를 가지지 않고 기능만 가진다. 애그리거트의 상태값이 필요하다면, 응용 서비스의 도움을 받아 메서드 파라미터를 통해 주입받을 수 있다.

 

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

전에 우리는 JPA 레포지터리 인터페이스는 도메인 영역에 포함시키고, 구현 클래스는 인프라 영역에 포함시켰다. 또한, 도메인 로직 관점에서 인터페이스를 작성했었다. 이와 비슷하다.

 

외부 시스템이나 타 도메인과의 연동은 도메인 서비스 포함시킬 수 있다. 가령 구현 부분이 HTTP 호출로 이루어져 있더라도 상관없다. 도메인 로직 관점에서 인터페이스를 작성한 뒤 도메인 서비스로 포함시키고, 구현 클래스를 인프라 영역으로 보내면 그만이다.

+ Recent posts