도메인 모델링 세미나 21
7월 6일부터 도메인 모델링 학습을 함께 하겠다고 하셨던 두 분의 동행은 아직 계속되고 있었다. 어제 모처럼 함께 점심을 먹고 이야기를 나눴는데, 화제 중에서 이벤트 정의에 대한 대화가 있었다.
상태도의 기원에 대해 배운 후에 훈장님(사진의 우측)이 상태도는 이벤트를 엄밀하게 정의해보면 검증이 된다는 말을 하자 동료는 감탄했다. 내가 덧붙여서 구조에 대해 검증하는 방법은 같은 경계 안에 있는 행위들로 하는 것이 기본이라고 말했는데, 그런 식의 대화로는 경험을 전달할 수는 없다는 점을 이후에 깨달았다.
바로 그 동료에게 상태도의 실전 예제로 과거에 내가 그렸던 금융시스템 결산 모델링 결과물을 보여준 일이 있었는데 그가 이를 떠올리길 기대하는 것은무리였다. 단순히 듣기만 해서는 둘을 연결 지을 수는 없는 일이었다.(기억은 그렇게 작동하지 않는다.)
그러는 중에 나중에 보려고 보관해둔 Vaughn Vernon의 링크드인 글이 눈에 띄었다. 이벤트가 행위(action)이라는 표현이 있는데, 그렇지 않다고 주장하는 짧은 글이다. 이벤트는 행위도 아니지만, 미래의 행위를 읽으켜야 하는 것도 아니라고 한다. 무슨 말일까?
이벤트라는 말은 굉장히 널리 쓰이는 말이라 조심할 필요가 있다. Vauhn Vernon이라는 사람의 저서와 활동을 아는 사람이라면 오해 소지가 적지만, 그가 태그에 표현한 대로 이벤트 주도 아키텍처 혹은 DDD 커뮤니티에서 말하는 이벤트에 대한 이야기다.
그에 따르면 이벤트는 행위가 일어났던 사실의 기록(factual record)이다. 이벤트는 행위를 뒤따르는 개념으로 규정한 것이다.[1]
EDA를 채용해서 경험과 지식을 갖춘 사람에게는 뻔한 이야기이고, 경험이 없는 사람에게는 자칫 말장난으로 들릴 수 있는 이야기를 왜 했을까?
단서는 그다음 문장에서 찾을 수 있다.
Consumers should translate events to commands to react to the events.
제목을 잘 뽑은 듯하다. 스스로 뿌듯해서 글 제목으로도 붙인다. 왜 혼자 자화자찬을 하고 있는지 독자들에게 설명해야겠다.
우리가 프로그래밍을 하면서 굳이 이벤트(Event)와 같은 복잡한 개념을 차용하는 이유가 무엇인가? <리팩토링을 내장할 수 있다면?> 편에서 좋은 코드에 대해 정의한 일이 있다.
좋은 코드 = 수정하기 쉬운 코드
글에서 Kent Beck의 연재 글 제목을 인용했는데, 그가 정돈(Tidyng)을 빨리 개발하기(Sooner)와 비교해보는 이유는 무엇인가?
내 생각에 정돈(Tidyng)은 이후에 수정하기 좋게 하는 일이고, 어떤 변화가 발생하면 즉각적으로 어디를 바꿀 수 있는 구조를 고려할 가능성이 높다. 우리는 이렇게 규칙을 정할 수 있다.
일단 변경이 필요하면 이벤트라는 것을 만들어서 저장하기로 하자
그에 따라 바뀌어야 하는 프로그램이 다수라면 이는 각자 알아서 하도록 하자는 것이다. 느슨한 결합을 이용하는 협업의 표준을 만든 것이라 할 수 있고, Event Driven Architecture의 효용성에 대한 안영회식 정의라고 할 수 있다.
그래서 이벤트에는 사실에 대한 기록만 충분하면 된다. 그러면 여기에 영향을 받는 프로그램들이 다시 (CQRS의 바로 그) 커맨드를 만들어서 필요한 수정을 하도록 구획이 잘 지어지게 하자는 것이 EDA가 변화에 대응하는 방식이라고 할 수 있다.
A command represents the potential for future action.
오늘은 조금 우아하게 글을 끝내보자. 글의 시작은 EDA 이야기가 아니라 상태도(혹은 추상적인 상태의 설계)에 대한 이야기였다.
상태도는 이벤트를 엄밀하게 정의해보면 검증이 된다
많은 프로그래밍 서적과 기법에서 Stateful 방식 대신에 Stateless를 쓰라고 설명한다. 그런데 각각이 무엇이고, 왜 그렇게 해야 하는지 설명은 부족하다. Stateful과 Stateless 차이를 명확하게 알려면 객체의 독립성(Atomicity)에 대한 명확한 인지나 구현 기준이 있어야 한다. 그걸 여기서 설명할 자신은 없지만, 필요한 만큼만 설명해보자.
어떤 프로그래밍 덩어리에 수정이 필요한 일이 발생했다고 하자. 그 프로그램을 담당한 개발자가 이벤트라고 구분한 별도의 코드나 레코드를 바꿔주면 되는 아키텍처가 있으면 그는 복잡하게 얽힌 다른 코드에 대해 고민할 필요가 없어 프로그래머로써의 삶의 질이 보장된다. :)
그런데, 개발자들이 모두 자기가 맡은 덩어리들 입장에서만 본다면 전체적인 일관성은 어떻게 보장할 수 있을까? 우리가 MSA를 채용할 때 필연적으로 만나는 문제는 바로 DBMS라는 솔루션 혹은 트랜젝션이라는 개념으로 처리하던 방식의 대안을 찾는 일이다.
결론부터 말하면 상호작용하는 전체 시스템 혹은 시스템의 시스템에 대한 상태가 완결성을 지녀야 한다. 그래서, 사고 실험에 능한 사람(혹은 모델링 훈련이 된 사람)은 상태도를 그려볼 수 있다. 하지만, 그 상태도가 완결성이 있는지 알려면 이들 시스템 전체에서 발생하는 이벤트를 정의해 보지 않고서는 장담할 수 없다.
같은 주제지만 검증의 맥락이 아니라 협업을 위한 프로그래밍 약속으로 바꾸면 바로 EDA 구현체가 된다. :)
[1] 파파고 번역을 했더니 이벤트는 '사건', 액션은 '행동'으로 번역했다.
5. 아주 이상적인 아키텍처
10. Repository 빌딩 블록에 대해 생각해보기
11. 맥락은 어떻게 표현할 것인가?
18. 도메인 모델링 절차에 대하여
19. 왜 도메인 모델링을 하는가?