DDD의 서비스 구조물이란 어떤 프로그램 덩어리인가?

즉흥적인 글을 하나 쓰다 말고 방치해뒀는데, 이제라도 보완해서 발행한다. 꽤 시간이 지난 글에 대해 독자 한분께서 댓글을 주셨는데, 주제 특성상 하염없이 미룰 가능성이 높아 즉흥적인 생각을 풀어놓는다. 그래서, 이번 글을 김성현님 특집이라고 해도 좋을 듯 하다.

지난 글에 대한 popit 독자님의 질문

지난 글에 대한 popit 독자님의 질문

마침 오전에 있던 서비스에 대한 짧은 대화

출근하자마자 위챗으로 한 지인께서 URL 하나를 보내오셨다. 2002년에 잠시 사용성Usability 테스트 도구를 만든 일이 있었다. 당시 대학원에 다니기도 했던 터라 해당 분야 논문에 해당하는 책도 보고 그래서인지 향수를 불러일으키는 글이었다. 다만, 정독할 소재는 아닌 듯 해서 쓱 훑어 봤는데, 잔상이 남는 이미지가 하나 있다. 아래 그림을 보면 Services는 Products 보다 높은 가격이고, 그 이유가 바로 고객 니즈 충족과 그에 따른 경쟁 우위라고 요약하는 듯하다.

The Progression of Economic Value model proposed by Pine and Gilmore

The Progression of Economic Value model proposed by Pine and Gilmore

이 그림을 본 직후 이를 연관이 맺어지는 전혀 다른 사건이 있었다. 복수의 경영자와 논의 과정에서 '서비스란 무엇인가?' 에 대해 의견이 오갔다. 그때 나눈 대화가 퇴근 후에도 뇌리에 남았다. 그리고, 위 그림을 보면서 서비스란 제품을 제공하면서 설명서를 제공하지 않아도 되도록 하는 어떤 활동일 수 있다는 생각도 잠시 했는데, 그 생각도 머리속에 머물러 있었다.

한 동료가 그리고 있는 그림을 보자

그러던 차에 이 글을 써야겠다고 최종 결정한 순간은 앞선 글에서 인용한 동료의 그림을 우연히 본 뒤다. 내 경험을 그냥 풀어서는 전달하는 일은 가치가 불분명하다. 하지만, 이 그림에서 서비스라는 소재를 꺼내면 다른 개발자들에게 작은 영감을 전달할 수도 있겠다 싶다.

자, 아래 그림을 보자. 온통 서비스 투성이다. :)

DDD-ValueObject-And-Microservice (5)

우리가 마이크로 서비스를 채택하고 있어서 네트워크 구간으로 분리되는 단위는 모두 서비스라고 부른다. DDD가 정의하는 구조물 이름인 서비스와는 매우 다른 뜻이다. 먼저 마이크로 서비스에서 서비스란 무엇인가? 이글에서는 살펴보지 않겠다. 아직 마이크로 서비스가 시장에서 쓸모를 확인하는 중이고, 산업 자체에서 아직 성숙해졌다고 보기는 어렵기 때문에 정의는 별 의미없다고 본다. 이 글에서는 DDD가 말하는 서비스에만 관심을 두려고 한다.

DDD 서비스란 무엇인가?

DDD가 말하는 서비스 정의[1]를 훑어보자.

When an operation does not conceptually belong to any object. Following the natural contours of the problem, you can implement these operations in services.

어렵다. 하나같이 답하기 모호한 이런 질문을 쏟아낼 수 있다.

  • 개념적으로 어떠한 객체에도 속하지 않는다는 말은 무엇인가?
  • 함수형 프로그래밍의 함수를 말하는가?[2]
  • natural contours of the problem는 어떻게 해석해야 하는가?

필자는 이에 대한 즉답 대신 위 그림을 조금 바꿔보면서 함께 답을 찾아보는 방법을 택하겠다.

조립물 후보는 모두 걸러보자

그림에서 조립물 혹은 Aggregate 후보를 표기해봤다. 따져보니 결국 UI의 요청을 직접 받는 녹색으로 칠한 영역과 Calculate Service를 제외하고는 모두 조립물로 분류할 수 있다.

조립물 후보를 걸러보기

조립물 후보를 걸러보기

위 내용을 이렇게 말할 수 있다.

  • 우리는 마이크로 서비스로 독립된 단위에 서비스라고 붙였다.
  • 그 중에서 Order Service를 포함해서 마이크로 서비스 하나가 독자적으로 데이터 무결성을 보장한다면 DDD 조립물로 분류할 수 있다.

만약에 데이터 무결성 보장 이외의 책임이 커지면 이를 분할하자.

이벤트 드리븐의 등장

이렇게 하고 나니 가장 먼저 달라지는 점은 개별 서비스(위 그림에서 주로 조립물에 해당)의 데이터 무결성은 각자 해결해야 한다는 점이다. 호출하는 앞쪽의 프로그램이 보장하던 것이 카프카라는 매개체를 통하긴 하지만, 각 개발자가 이벤트 기준으로 Pub/Sub에 해당하는 부분을 인지하며 구현해야 했다. 이러한 협업의 변화 과정을 거치는 과정에서 가장 큰 회의실에 관련 개발자가 모두 모여 소통하며 구조를 바꾸는 장관을 목격하기도 했다. 오랫동안 꿈꾸던 프로그램 구조를 내 취향이 아니라 조직의 필요에 의해 구현되어지는 광경을 멀리서 지켜봤다. 아래는 필자 협업 시스템에서 찾은[3] 이벤트에 대해 동료 PO에게 설명하는 글이다.

6개월 전에 두레이에 있던 이벤트 관련 기록

6개월 전에 두레이에 있던 이벤트 관련 기록

이렇게 되면 자연스럽게 중앙 통제 방식이 사라진다. UI쪽에서 중간에 있던 Order를 건너 뛰고 다른 서비스에 직접 접근하기 시작하면 그러한 현상은 더욱 강화된다. 개별 마이크로 서비스 차원에서는 DBMS에 보장하던 트랜젝션 관리에 의존할 수 있지만, 서비스 사이에 연관관계가 있다면 온전히 DBMS 트랜젝션으로 처리할 수 없다.

필자가 이 일이 있기 한참 전에 즉흥적으로 서비스 일관성Service Consistency이란 조어를 쓴 일이 있는데,  그 기록을 찾게 되는 순간이다. 와우~

개발 업무 일상의 두레이 댓글

개발 업무 일상의 두레이 댓글

다시 DDD 서비스로 돌아오면

이렇게 되면 개별 조립물에게 한 가지 부담이 더 간다. 바로 서비스 수준의 일관성 앞에서 서비스 일관성이라 명명한 부분에 대한 책임이다. 이 경우 수정하는 주기나 이유가 비슷한 프로그램을 한 덩어리로 묶어야 한다는 원칙을 생각해보자. 그러면, 높은 추상 수준이지만 데이터를 관리하는 코드랑 구분하여 다양한 시장의 요구를 UI로부터 받아낼 어떤 덩어리를 상상할 수 있다. 현재 우리 시스템에서는 DDD 서비스라고 특정할 내용이 별도 객체(혹은 마이크로 서비스)로 분리되어 있지는 않지만, 떨어뜨릴 후보는 충분히 생각해볼 수 있다.

지금 내 입장에서는 다양한 UI와 붙여서 쓸 수 있는 다목적 서비스 다시 말해 수익성이 높은 코드를 DDD 서비스로 지정하고 싶다. 필자의 위치가 기획자이기도 하고, 무엇보다 회사를 책임지는 몸이기 때문에 그렇다. 하지만, 그런 내 입장을 내려놓고 순수하게 엔지니어 입장에서 최종 사용자 입장에서 서비스 일관성보장을 위한 코드를 DDD 서비스로 묶을 수도 있다고 생각한다.

주석

[1] https://en.wikipedia.org/wiki/Domain-driven_design

[2] 필자는 함수형 프로그래밍의 함수가 DDD 서비스 구현법 중 하나라고 생각한다.

[3] 애초 popit에 이벤트에 대한 설명 글을 쓰려고 올려 놓았던 것을 가로채서 여기서 써먹는다.


Popit은 페이스북 댓글만 사용하고 있습니다. 페이스북 로그인 후 글을 보시면 댓글이 나타납니다.