brunch

사용자 경험과 연결되는 도메인 이벤트 설계 품질

어떻게 하면 모델링을 잘할 수 있을까?

by 안영회 습작

<사건 발생을 이벤트 정의와 발행으로 모방하기>를 읽고 소프트웨어 설계를 공부하는 바로 그 동료가 다시 자신의 모델링에 대해 피드백을 요청했습니다. 그의 진정성이 느껴져 시간을 내어 보답(?) 하지 않을 수 없었습니다. :)


주차 정산 도메인의 명백한 사건들

동료가 다루는 도메인은 주차장의 비용 정산 비즈니스입니다. 요즘은 자동 정산 시스템이 깔린 주차장이 많기 때문에 차량을 소지하신 분들은 해당 업무에 종사하지 않아도 충분히 추정할 수 있는 예제가 될 수 있겠네요. 여기서 출차와 입차는 너무나도 명백한 사건이죠. 둘 다 도메인 이벤트의 전형이라고 할 수 있겠습니다.


주차 정산 도메인의 명백하지 않은 사건들

동료가 모호하게 느끼는 부분들이 있는데, 그간 쭉 이벤트를 다뤄왔으니 이벤트에 관한 것부터 살펴보겠습니다. 첫 번째는 할인도 이벤트냐 하는 부분입니다. 어떻게 해야 할까요?

매번 통용되는 정답은 없습니다.[1] 그러니 '저라면'이라는 단서를 붙이겠습니다. 저라면 이벤트로 보지 않을 것입니다. 왜냐하면 계산을 해야 할 시점에 할인 여부를 한 번에 판단해야 하기 때문입니다. 그렇게 하려면 계산이라는 행위를 하기 위한 이벤트가 필요할 뿐, 할인을 위해 별도 이벤트가 있어야 한다면 상당히 불편할 듯합니다. 이벤트를 발생시킬 누군가가 (사람이라면) 실제로 불편을 겪거나 프로그램이 필요 이상으로 복잡해질 수 있습니다. 그러니 꼭 그래야 할 필요를 느끼기 전까지는 이벤트로 만들지 않을 듯합니다.


오히려 동료가 이벤트 후보를 빠트렸다는 생각을 하게 됩니다. 할인 이전에 일단 정산을 하려면 '언제 정산을 할 것인지?'를 알려 주는 사건이 있어야 합니다. 경험을 떠올려 시스템이 없는 곳을 생각해 보면 출차 시점에 사람이 정산을 합니다. 그런데 어떤 곳은 인건비를 줄이려고 출차할 때 사람이 없는 경우도 있습니다. 그중에 사전 정산 기능이 없는 곳을 생각해 보면 운전자가 창문을 열고 카드를 넣거나 현금을 지불해야 합니다. 이런 경우는 사전 정산이 되는 곳에 비해 불편하기도 하고, 할인 처리도 쉽지 않습니다.


사용자 경험과 연결되는 도메인 이벤트 설계 품질

실제로 이런 곳을 경험한 일이 있는데, 운전자가 버튼을 누르면 스피커 폰으로 원격에 있는 누군가와 대화를 해야 했습니다. 그런 다음에 사람이 어딘가에서 할인 처리를 해 주고 차단기가 열려 출차할 수 있었죠. 소심한 분들은 식은땀이 흐를 수 있고, 뒤에서 기다리는 운전자들이 불편할 수 있습니다.


그래서, 대형 마트와 같이 시스템이 잘 된 곳들은 주차장 가는 길에 정산 시스템을 둡니다. 정산 시스템은 일반 사용자들이 쓰는 말이고, 프로그래머나 개발자를 위한 표현으로는 정산 이벤트를 발생시킬 사용자 인터페이스라고 할 수 있습니다.(정산이 아니라 ‘출차 전 정신 완료’를 이벤트로 만들 수도 있습니다.)


여기서 동료의 또 다른 질문을 살펴보게 되는데요. 사용자와 시스템의 경계를 분명하게 설정하지 않은 상황으로 보입니다. 2022년에 다른 동료에게 설명했던 <시스템 구동의 맥락(context) 파악하기>가 덜 된 것이죠.

이 글이 또 다른 예시가 되겠네요. 액터를 도입할 때입니다.


액터 식별을 통해 시스템 경계와 상호작용을 드러내기

사용자와 액터가 어떻게 다른 지도 자연스럽게 설명이 되겠네요. 액터에 대한 설명이 더 필요하신 분은 이전에 제가 쓴 <모델링 과정을 역추적하기 위한 초벌 메모>와 <모델링을 Actor로 시작한다는 의미는 무엇인가?>를 참조하실 수 있습니다. 그림 왼쪽은 PlantUML로 그린 쓰임새도Use case diagram[2]이고 오른쪽은 식별한 이벤트 정의 클래스도입니다.[3]

이벤트 이름도 정제했습니다. 엄밀하게 따지면 입차와 출차는 차단기로 시스템이 막고 있기 때문에 액터의 욕구에 부응해서 주차장 시스템이 허용해야 하는 쓰임새로 볼 수 있습니다. 이러한 쓸모(쓰임새나 같은 말)가 작동하기 위해서 액터는 입차 요청이나 출차 요청을 할 수 있죠. 보통은 차단기 앞에 서는 것으로 족합니다. 센서가 작동하여 알 수 있는 정도는 이제는 사회적으로 보편적인 기능이 된 상황이니까요.


정산 요청 이벤트는 액터가 다릅니다. 차단기에 도착했을 때 하게 되면 앞서 설명드린 대로 매우 불편하죠. 운전자가 차에 타기 전에 미리 해 두고 차에 탑승하면 편합니다. 그러니 운전자가 액터가 되어야 하겠죠. 운전가가 아닌 사람이 정산 요청을 할 수 있습니다만, 엄밀함의 수준은 도메인에 따라 달라집니다. 여기서는 여기까지는 고려하지 않기로 합니다.


동료의 의문이 더 남아 있는데, 글이 길어져서 잠시 쉬었다가 다음 글에서 다루기로 합니다.


주석

[1] 그렇지 않다면 머지않아 그 프로그램은 인공지능이 짜게 될 테니, 곧 사라지겠죠.

[2] 그림에 쓰인 UML 소스는 다음과 같습니다.

@startuml

left to right direction

actor "차량" as car

actor "운전자" as person

rectangle Restaurant {

usecase "입차" as UC1

usecase "정산" as UC2

usecase "출차" as UC3

}

car --> UC1

person --> UC2

car --> UC3

@enduml

[3] 그림에 쓰인 UML 소스는 다음과 같습니다.

@startuml

class 입차요청이벤트 <<Domain Event>>

class 정산요청이벤트 <<Domain Event>>

class 출차요청이벤트 <<Domain Event>>

@enduml


지난 어떻게 하면 모델링을 잘할 수 있을까? 연재

(24회 이후 링크만 표시합니다.)

24. 관계(關係)라는 말과 연관(聯關)이라는 말의 차이

25. 의존Dependency와 연관을 잘 쓰기

26. 모듈화: 다시 쓰는 동시에 유연성을 줄 수 있나?

27. 자기 조직화를 소프트웨어에 구현할 수 있는가?

28. UML 혹은 객체지향 관계 중 합성과 집합의 차이

29. 상태 관리에 대한 이해가 필요한 비대칭 분산 시스템

30. 복잡한 클래스를 엮어서 단순한 복합체를 만드는 OCP

31. 사건을 포착하여 객체로 만드는 이벤트에 대한 설명

32. UI 디자이너가 만든 기획서로 객체 지향 모델링하기

33. Domain-driven 업무 소통: 업무를 객체로

34. ECB 패턴과 2025년의 실효성 해석

35. 사건 발생을 이벤트 정의와 발행으로 모방하기

36. 사건이라는 개념을 프로그래밍 이벤트로 응용하기

37. 프로그래밍에서 이벤트는 모듈화를 위해 도입한 개념

keyword
작가의 이전글우연히 목차만 보아도 영감을 주는 책을 만나다