Self-Development/Study

what is a domain services?

JeongKyun 2024. 9. 28.

에릭 에반스는 도메인 서비스를 다음과 같이 말했다.

엔터티에 부여하기 적합하지 않은 책임을 도메인 서비스에 부여하라

즉, 도메인 서비스는 말 그대로 도메인을 위해 존재하는 객체이므로 기술에 의존성이 없는 POJO 형태로 구현되어야한다.

 

반 버논의 "도메인 주도 설계 구현"에서는 도메인 서비스를 사용해야할 때 세가지 휴리스틱을 제시했다.

 

  1. 중요한 비지니스 프로세스를 수행할 때
  2. 어떤 컴포지션에서 다른 컴포지션으로 도메인 객체를 변환할 때
  3. 하나 이상의 도메인 객체에서 요구하는 입력값을 계산할 때

 

중요한 비지니스 프로세스를 수행할 때

사례로 에릭 에반스는 도메인 주도 설계에서 계좌 이체로 설명했다.

계좌 이체는 입금, 출금, 잔액조회 같은 계좌의 책임이 아니라 두 계좌간 연속적인 입금과 출금의 과정이다.

 

계좌 이체는 TransferMoneyService라는 도메인 서비스로 정의하고 이체가 성공하면 그 결과인 TrasferMoney 엔터티를 반환하도록 한다. 즉, 위 비지니스(계좌이체)를 수행하고자할 때 계좌(Account)라는 도메인 객체의 책임이 아닌 입금, 출금의 과정들이 필요하다. 이럴 때 도메인 서비스를 정의하여 구현하는것이라는것을 보여준다.

 

그리고 도메인 서비스를 사용할 때 아래와 같은 주의점을 강조한다.

무분별한 도메인 서비스의 사용이 빈약한 도메인 모델을 초래하기때문에 꼭 필요한 경우가 아니라면 자제할 것을 강조한다.

 

느낀점

위 말이 며칠전 필자가 작성했던 애그리거트 디자인하기 글과 관련있다고 생각했는데, 결국 도메인 객체에 응집되어야 할 논리가 도메인 객체의 책임이 도메인 서비스로 빠져나가서 빈약한 모델을 초래한다고 생각했다. 많은 공감이 된 항목이다.

 

어떤 컴포지션에서 다른 컴포지션으로 도메인 객체를 변환할 때

특정 도메인 객체를 사용하기위해 다른 도메인 객체나 데이터 전송 객체로 변환하거나, 반대로 데이터 전송 객체를 도메인 객체로 변환하는데 사용한다.

 

예로는 주문 서비스를 만들 때, 배송지라는 엔터티가 존재할 수 있다.

이 때 나의 배송지 엔터티를 주문의 주문 배송지 값 객체로 변환할 때 도메인 서비스를 사용할 수 있다고 말한다.

 

느낀점

결국 도메인 계층에서 이루어지는 작업이다보니 계층 간 의존성을 헤치는것은 아니지만, 외부 도메인 객체 간 서로 의존성이 강해지면 발생하는 문제들도 꽤 있기때문에 이런 converting, mapping 논리들을 도메인 서비스를 활용해서 사용하는 방법을 제시했다고 생각했다.

 

이번 항목에 대해선 맥락은 충분히 동의되고 이해가 가나 이를 도메인 서비스로 식별하기보단 도메인 변환기(Domain Converter) 정도가  낫지않나란 생각을 했다. 이유는 계층 아키텍처(Layer Architecture)에 익숙한 개발자들에게는 위 변환 로직을 서비스로 식별하여 명명하고 진행하면 많은 혼선을 초래할 수 있을거같다고 생각했기 때문이다.

 

(그런데? 마침 접미사에 Service보다는 Policy나 Converter같은 문제 영역에서 클래스 역할을 더 명확하게 표현할 수 있는 이름을 사용하는게 좋다고도 언급했구나..)

 

하나 이상의 도메인 객체에서 요구하는 입력값을 계산할 때

예를 들어 전화 상담원의 일일 총 통화시간을 계산할 때, 애플리케이션 서비스에서 통화 목록을 조회한 후 반복문을 이용해 누적값을 계산할 수 있다. 하지만 총 통화 시간 계산은 비지니스와 밀접하게 연관되어 있으므로 애플리케이션 서비스의 책임으로 모두 부여해버리기엔 적절하지 않을것이다.

 

반대로 "통화" 라는 엔터티에 계산 책임을 모두 부여하면 다른 엔터티에 의존성을 가져야하고 이는 불필요한 의존성을 가지므로 이또한 적절치 않다. 따라서, 총 통화시간처럼 도메인과 밀접하게 관련된 기능이면서 엔터티나 값 객체에 어울리지않는 책임을 도메인 서비스에 부여한다.

 

 

느낀점

이것도 많이 공감되는 내용이다. 다른 도메인 객체의 역할 또는 어떠한 인풋들이 필요한 경우가 많이 존재한다. 풍부한 도메인 모델을 만들기 위해 노력하다보면, 위 논리들을 어떻게 넣지? 어떻게 더 풍부하게 만들까란 욕심에 많은 고민이 들때가있다. 그런 부분에 대해 꽤 깔끔하게 정리해서 제시했다고 생각한다.

 

그리고 앞서 설명한 세가지 사례를 보았을 때, 도메인 서비스는 전달받은 파라미터만 사용하여 비지니스 로직을 수행하고 그 결과를 반환하는 무상태라는 공통된 특징을 가진다. 즉, 부수효과를 갖지않는 비지니스 논리를 수행하는 도메인 객체를 위한 서비스라는것이다.

반응형

댓글

💲 많이 본 글