- 출처: 도메인 주도 설계 - 에릭 에반스
- 들어가기전에
DDD의 Service를 언급하기전에 한 가지 확실히 해두고 싶은 점이 있다. 이 글에서 언급하고자 하는 DDD의 service는 project에서 많이들 구성하는 controller, service, repository 계층 에서 말하는 응용 계층의 service와 다르다.
- Service
service는 개념적으로 어떤 객체에도 종속되지 않는다. 어떤 객체에 종속시키기 애매한 무엇인가가 있다면 억지로 해당 객체로 밀어넣으려고 하기 보다는 service로 추출하여 모델링에 포함시키는 방법도 존재한다.
보통 service는 entity나 VO에 포함되지 않는 도메인의 연산이 활동이나 행동으로 나타나는 경우가 많다. 이런 도메인 연산은 여러 도메인 객체를 모아 조율하는 역할을 하는 형태도 많다. 이를 강제로 객체에 포함시키면 여러 도메인 객체가 서로 의존 하므로 단독 개념으로 해결할 수 있는 문제도 뒤죽박죽으로 만들기 쉽다.
만약 특정 연산을 하는것이외에 모델로서 의미가 없고 네이밍을 하려고할 때 "Manager"라는 이름이 떠오른다면 Service 모델인지 한번 생각해볼 여지가 있다.
Service가 어떤 객체에 종속되지 않는다고 해서 연산 명칭을 너무 기술적으로 지으면 안된다. 엄연히 도메인의 모델이기 때문에 도메인 용어를 차용하는것이 좋다. Service의 매개변수와 반환형은 도메인 객체여야 한다.
잘 만들어진 service는 몇 가지 특징을 지닌다.
- 연산이 entity, VO의 일부를 구성하지 않고 도메인의 개념과 연관된다.
- 연산이 상태를 갖지 않는다.
- I/F가 도메인 모델 외적 요소 측면에서 정의된다.
- Service와 격리된 도메인 계층
이 글의 초반에 언급한 대로 도메인이 아닌 다른 계층에도 service가 존재한다. 도메인 service와 응용 service는 인프라 계층과 협업한다. 여기서 인프라 계층과 협업한다는 의미는 "잔고가 일정 금액 이하일 때 e-mail로 통보한다."와 같은 요구사항에서 "e-mail로 통보"하는 부분에 해당한다.
여기에서 그럼 응용 service와 도메인 service가 어떻게 다른것인가라는 의문이 들 수 있다. 예제를 통해 더 쉽게 이해해보자.
위의 요구사항에서 "계좌가 일정 금액에 도달했는지"에 대한 것은 도메인 책임이다. 왜냐하면 "계좌"는 도메인에서 나올법한 용어이며 도메인 책임이 더 어울리기 때문이다.
만약 "거래 분석 내역을 스프레드 시트 파일로 내보낸다."면 이런 내보내는 구현은 응용 service 가 더 어울린다. "스프레드 시트"와 같은 형식은 핵심 은행업무가 아니기 때문이다.
"A계좌에서 B계좌로 이체한다."는 요구사항이 있다면 도메인 service가 될 가능성이 크다. 이체한다는것은 도메인의 entity나 vo로 하면 안되는건가? 왜 핵심 객체인것 같은데 service가 되어야 하지? 라는 의문이 들 수 있다.
우선 A계좌에서 B계좌로 자금이 이체될 때, 사실 대부분의 일은 "계좌"가 수행하게 될것이다. "이체"라는 행위를 "계좌"객체에 위임하는건 부자연스럽다고 할 수 있다. "이체"라는 개념은 이미 2개 "계좌"가 참여하기 때문이다. 앞에서 도메인 연산은 여러 도메인 객체를 조율하는 역할을 한다고 했던 말을 떠올리면 이해가 더 수월할것이다.
- 구성 단위
구성 단위가 적당한 service는 대형 시스템에서 재사용되기가 수월하다. 만약 구성단위를 너무 세밀하게 잡으면 도메인 지식이 새어나와서 행위 조정이 응용계층으로 이동될 가능성이 크므로 주의하자.
'Concepts > SW Design' 카테고리의 다른 글
DDD - 도메인 객체의 lifecycle과 Aggregate (0) | 2022.09.10 |
---|---|
DDD - Module (package) (0) | 2022.08.07 |
DDD - Value Object (0) | 2022.07.19 |
DDD - Entity (0) | 2022.07.17 |
DDD - S/W와 모델 (0) | 2022.07.16 |
댓글