DDD 6. 도메인 서비스

2 minute read

⌜도메인 서비스

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

  • 도메인 영역의 코드를 작성하다 보면, 한 애그리거트로 기능을 구현할 수 없을 때가 있다.
  • 이 경우, 한 애그리거트에 넣기 애매한 도메인 기능을 억지로 특정 애그리거트에 구현하면 안 된다.
  • 억지로 구현하면 애그리거트는 자신의 책임 범위를 넘어서는 기능을 구현하기 때문에 코드가 길어지고 외부에 대한 의존이 높아진다. 또한 코드를 복잡하게 만들어 수정을 어렵게 만드는 요인이 된다.
  • 게다가 애그리거트의 범위를 넘어서는 도메인 개념이 애그리거트에 숨어들어 명식적으로 드러나지 않게 된다.
  • 이런 문제를 해소하는 가장 쉬운 방법은 도메인 기능을 별도 서비스로 구현하는 것이다.

2. 도메인 서비스

  • 도메인 서비스는 도메인 영역에 위치한 도메인 로직을 표현할 때 사용한다.
  • 주로 다믐 상황에서 도메인 서비스를 사용한다.

    계산 로직 : 여러 애그리거트가 필요한 계산 로직이나, 한 애그리거트에 넣기에는 다소 복잡한 계산 로직 외부 시스템 연동이 필요한 도메인 로직 : 구현하기 위해 타 시스템을 사용해야 하는 도메인 로직

  • 할인 금액 규칙 계산 처럼 한 애그리거트에 넣기 애매한 도메인 개념을 구현하려면 애그리거트에 억지로 넣기 보다는 도메인 서비스를 이용해서 도메인 개념을 명시적으로 드러내면 된다.
  • 응용 영역의 서비스가 응용 로직을 다룬다면 도메인 서비스는 도메인 로직을 다룬다.
  • 도메인 영역의 애그리거트나 밸류와 같은 구성요소와 도메인 서비스를 비교할 때 다른 점은 도메인 서비스는 상태 없이 로직만 구현한다는 점이다. 도메인 서비스를 구현하는 데 필요한 상태는 다른 방법으로 전달받는다.
  • 도메인 서비스를 사용하는 주체는 애그리거트가 될 수도 있고 응용 서비스가 될 수도 있다.

    특정 기능이 응용 서비스인지 도메인 서비스인지 판단하는 기준

    • 해당 로직이 애그리거트의 상태를 변경하거나 애그리거트의 상태 값을 계산하는지 확인해보면 된다.
    • 도메인 로직이면서 안 애그리거트에 넣기 적합하지 않으므로 이 두 경우에 대한 로직은 도메인 서비스로 구현하게 된다.
  • 외부 시스템 연동과 도메인 서비스
    • 외부 시스템이나 타 도메인과의 연동 기능도 도메인 서비스가 될 수 있다.
    • 여기서 중요한 점은 도메인 로직 관점으로 해당 기능을 위한 인터페이스를 작성하는 것이다. 그리고 해당 기능의 인터페이스를 구현한 클래스는 인프라스트럭쳐 영역에 위치해 기능을 구현한다.
  • 도메인 서비스의 패키지 위치
    • 도메인 서비스는 도메인 로직을 표현하므로 도메인 서비스의 위치는 다른 도메인 구성요소와 동일한 패키지에 위치한다. (repository, model, domain service)
    • 도메인 서비스의 개수가 많거나 엔티티나 밸류와 같은 다른 구성요소와 명시적으로 구분하고 싶다면 domain 패키지 밑에 domain.model, domain.service, domain.repository 와 같이 하위 패키지를 구분하여 위치시켜도 된다.
  • 도메인 서비스의 인터페이스와 클래스
    • 도메인 서비스의 로직이 고정되어 있지 않은 경우 도메인 서비스 자체를 인터페이스로 구현하고 이를 구현한 클래스를 둘 수도 있다. 특히 외부 시스템이나 별도 엔진을 이용해서 구현할 때 인터페이스와 클래스를 분리하게 된다.
    • 도메인 서비스의 구현이 특정 구현 기술에 의존하거나 외부 시스템의 API를 실행한다면 도메인 영역의 도메인 서비스는 인터페이스로 추상화해야 한다. 이를 통해 도메인 영역이 특정 구현에 종속되는 것을 방지할 수 있고 도메인 영역에 대한 테스트가 쉬워진다.
-->

Categories:

Updated:

Comments