Skip to content

Latest commit

 

History

History
52 lines (28 loc) · 4.94 KB

DomainService-DomainEvent.md

File metadata and controls

52 lines (28 loc) · 4.94 KB

도메인 서비스와 도메인 이벤트

도메인 서비스

책에 있는 내용

도메인 서비스는 DDD 책에 Service라는 제목으로 설명돼 있다.

DDD 책이 늘 그렇듯 장황하기 짝이 없는데,
책에 써있는 것을 얼추 요약하면 다음과 같다.

  • 어느 하나의 엔티티나 밸류객체에 속하지 않고 여러 엔티티나 밸류객체에 걸친 데이터를 사용하는 연산이 있을 때, 문맥에 맞지 않게 어느 할 쪽의 엔티티나 밸류객체에 로직을 우겨 넣지 말고 도메인 서비스에 두자.
  • 연산이 상태를 갖지 않는다.

그러면서 도메인 서비스의 예로 들고 있는 것이 계좌 이체다.

계좌 이체는 상태 변경이 수반되는 대표적인 케이스인데 이걸 도메인 서비스로 구현한다고 하니 도메인 서비스는 상태 변경이 수반되는 곳에 사용해도 되나보다라고 이해하게 됐다.

그리고 책에서 애그리것(aggregate)을 설명하기 전에 도메인 서비스 먼저 설명하는 바람에, 도메인 서비스 설명에는 애그리것이 전혀 언급되지 않고, 여러 엔티티/밸류객체에 걸친.. 이라고 설명되고 있다.

책과 다르게 이해

하지만 DDD를 적용하면서 개발하다보면 도메인 서비스는 엔티티/밸류객체 보다는 데이터 변경의 단위/경계이고 트랜잭션 경계이기도 한 애그리것과 연관지어 이해하는 것이 더 타당하다는 생각이 든다. 그래서 '여러 엔티티/밸류객체'보다는 '여러 애그리것'에 걸친 데이터를 사용하는 작업에 도메인 서비스가 사용된다 라고 이해하는 것이 더 낫다고 본다.

애그리것이 트랜잭션 경계인데, 도메인 서비스에서 여러 애그리것의 상태를 변경한다면 특별한 조치를 취하지 않는 한 하나의 트랜잭션 안에서 여러 애그리것의 상태가 변경될 수 있다. 이렇게 되면 데이터 변경의 경계가 애그리것이 아닌 도메인 서비스가 되고 이는 애그리것의 개념에 부합하지 않는다.

따라서 도메인 서비스는 여러 애그리것에 걸친 데이터를 상태 변경 없이 읽어서 사용하기만 하는 로직에 적용하는 것이 타당하다고 생각한다.

다행스럽게도 Learning DDD 에서도 아래와 같은 설명이 나온다.

Domain services make it easy to coordinate the work of multiple aggregates. However, it is important to always keep in mind the aggregate pattern’s limitation of modifying only one instance of an aggregate in one database transaction. Domain services are not a loophole around this limitation. The rule of one instance per transaction still holds true. Instead, domain services lend themselves to implementing calculation logic that requires reading the data of multiple aggregates.

도메인 서비스를 사용하면 여러 애그리것에 걸친 작업을 쉽게 조율할 수 있다. 하지만 하나의 데이터베이스 트랜잭션에서는 오직 한 개의 애그리것 인스턴스만 변경한다는 애그리것 패턴의 제약을 잊지 말아야 한다. 도메인 서비스는 이런 제약을 우회하는 개구멍이 아니다. 하나의 트랜잭션에 하나의 애그리것만 변경한다는 규칙은 도메인 서비스를 사용할 때도 변함 없이 지켜져야 한다. 그래서 도메인 서비스는 여러 애그리것에 걸쳐 있는 데이터를 읽고 계산하는 로직을 구현하는 데 사용하는 것이 적합하다.

이제 도메인 서비스를 나만의 언어로 정의해보면 다음과 같다.

도메인 서비스는 여러 애그리것에 걸쳐 있는 데이터를 읽어서 상태 변경 없는 작업을 수행하는 무상태 객체로서 도메인 계층에 위치 한다.

그럼 여러 애그리것의 상태 변경을 유발하는 로직은 어떻게 구현해야 하나? 그럴 때 사용하는 것이 바로 도메인 이벤트다.

도메인 이벤트

도메인 이벤트는 도메인 서비스에 비하면 매우 간단한 개념이다.

  • A 애그리것과 B 애그리것의 상태를 변경하는 상황에서,
  • A 애그리것과 B 애그리것을 한 곳에 모아서, A의 상태를 변경하는 곳에서 B의 상태도 함께 변경하도록 구현하지 말고,
  • A 상태 변경 후 A 상태가 변경됐다는 이벤트 C를 발행하고,
  • B에는 이벤트 C에 대한 이벤트 핸들러를 두고 C 발행 시 이벤트 핸들러에서 B 상태를 변경하도록 구현하는 방식이다.

이벤트를 사용해서 A와 B의 결합을 없애고 격리해서 처리하는 방식이고, 애그리것 패턴의 규칙처럼 A 상태 변경과 B 상태 변경은 다른 트랜잭션에서 처리하고 최종적 일관성(Eventual Consistency)을 적용하는 게 원칙이지만, 도메인 계층에 있는 A 입장에서는 그저 이벤트를 발행할 뿐 서비스 계층에서 처리하는 트랜잭션 처리에 대해서는 알지 못한다.