Event Storming – pierwszy krok do DDD?
„In any Event Storming session of all different kinds, everyone knows what everyone else knows“ - Dan North
Event Storming jest metodą odkrywania i konkretyzowania informacji o domenie biznesowej, w ramach której wytwarzane jest oprogramowanie. Handel, Telekomunikacja, Finanse, Edukacja, Prawo, Medycyna – domen biznesowych, z którymi w codziennej pracy spotykają się programiści i eksperci techniczni można wymieniać jeszcze wiele. Co więcej, często zmiana projektu pociąga za sobą zmianę domeny biznesowej, w ramach której pracujemy.
Jak zatem zdobyć informacje potrzebne do zaprojektowania oprogramowania wysokiej jakości dla domeny, której nieraz całkowicie nie znamy? Jedną z odpowiedzi może być Event Storming, a także związana z nim koncepcja Domain-Driven Design (DDD). W artykule tym przedstawione zostaną podstawowe informacje o Event Stormingu, korzyści z niego płynące, a następnie jego przebieg krok po kroku – na przykładzie warsztatu przeprowadzonego w FIS-SST przez zespół R&D.
Event Storming – Podstawy
Kto bierze udział?
Jest to zazwyczaj kilkugodzinny warsztat, w którym uczestniczą:
- eksperci techniczni, jak np. programiści, analitycy, czy właściciele produktu (PO),
- eksperci domenowi ze strony klienta/biznesu,
- tzw. facilitator - osoba zaznajomiona z techniką Event Stormingu, dbająca o sprawny i prawidłowy przebieg warsztatu.
Na czym to polega?
Sama forma warsztatu wydaje się dość prosta – do dyspozycji mamy dużą tablicę czy ścianę oraz mnóstwo różnokolorowych karteczek. Każdy z uczestników identyfikuje zdarzenia („Domain Events”), które występują w trakcie działania programu – np. „Utworzono konto użytkownika”, „Zamówiono towar”, czy „Wygenerowano fakturę”. Zdarzenia te zapisuje się na karteczkach i umieszcza na tablicy.
Jak zapewne można zauważyć, powyższe przykłady zdarzeń to bardzo ogólne pojęcia. Podczas Event Stormingu staramy się nie korzystać ze słownictwa fachowego i języka ściśle specjalistycznego. Celem jest, aby każdy rozumiał każdego, a używane określenia funkcjonowały w ramach danej domeny biznesowej.
Powyższe zdarzenia domenowe stanowią punkt wyjścia do dalszych pytań – co należy zrobić, aby miało miejsce zdarzenie „Utworzono konto użytkownika”? Program musi otrzymać sygnał, czyli musi być przekazana komenda („Command”) taka, jak np. „Utwórz konto”. Ale kto lub co jest źródłem takiej komendy? Czy to użytkownik sam tworzy swoje konto, poprzez rejestrację? Czy może konto użytkownika generowane jest automatycznie, na podstawie informacji otrzymanych z systemu zewnętrznego? I tu dochodzimy do kolejnego elementu identyfikowanego podczas warsztatu, którym są tzw. aktorzy („Actors”) wywołujący daną komendę.
Ustalenia dotyczące komend i aktorów też trzeba jakoś zapisać. Oczywiście w formie kolejnych karteczek, które jedna za drugą trafiają na coraz bardziej zapełniającą się tablicę. Na dalszym etapie warsztatu grupuje się powiązane ze sobą elementy – wyodrębniać zaczynają się tzw. agregaty („Aggregates”).
Po co to wszystko?
Wszystkie wyżej wspomniane elementy – zdarzenia domenowe, komendy, aktorzy, a następnie ustalone agregaty – sprawiają, że uczestnicy warsztatu zaczynają jasno rozumieć, jak funkcjonować ma modelowane oprogramowanie. Osoby uczestniczące w Event Stormingu same identyfikują procesy zachodzące w ramach wytwarzanego oprogramowania i osadzają je w domenie biznesowej. Po takim warsztacie eksperci domenowi mają jaśniejszy obraz tego, jak działać będzie produkt, a eksperci techniczni dochodzą do momentu, w którym utworzone agregaty i uzyskaną wiedzę biznesową mogą przenieść na kod zgodny z zasadami Domain-Driven Design.
Co daje nam Event Storming?
Zrozumienie domeny
Podczas Event Stormingu następuje wymiana wiedzy pomiędzy ekspertami technicznymi a ekspertami domenowymi. Nie rozmawia się o bazach danych, frameworkach, czy mapowaniach relacyjno- obiektowych. Zamiast tego, wszyscy uczestnicy posługują się pojęciami domenowymi. Eksperci techniczni zapoznają się dzięki temu z domeną, a eksperci domenowi zgłębiają sposób działania danego oprogramowania.
Wspólny język
Jako styk biznesu i programowania, Event Storming pozwala ujednolicić pojęcia używane we współpracy z klientem. A wspólny i jednolity język to już spory krok do stworzenia projektu na podstawie Domain-Driven Design.
Szybkość działania
W przypadku nowych dopiero rozpoczynających się projektów, Event Storming jest alternatywą dla innych, dłuższych procesów planowania wstępnego. Zebranie w ramach jednego, kilkugodzinnego warsztatu różnych osób zaangażowanych w dany produkt, już na tak wczesnym etapie jego tworzenia, może być korzystniejsze niż odkrywanie poszczególnych wymogów produktowych dopiero w trakcie developmentu.
Dystrybucja wiedzy
Event Storming propaguje wiedzę – tak wewnątrz zespołów, jak i pomiędzy nimi. Taka dystrybucja wiedzy między różne osoby zaangażowane w wytwarzanie oprogramowania przeciwdziała tworzeniu tzw. silosów wiedzy. Specjalistom technicznym daje to możliwości nauki i większego zaangażowania w projekt, a także zapewnia płynność prac w projekcie, na wypadek zmian kadrowych.
Zapewnienie jakości
Event Storming przekłada się nie tylko na zrozumienie domeny, ale także na dogłębną analizę zależności pomiędzy poszczególnymi funkcjonalnościami oprogramowania. A to właśnie osadzona w wiedzy domenowej, pełna świadomość procesów zachodzących w wytwarzanym produkcie jest jednym z czynników prowadzących do dostarczenia produktu wysokiej jakości.
Identyfikacja problemów
Również długo funkcjonujące projekty zyskać mogą na wdrożeniu Event Stormingu jako narzędzia analizy problemów, używanego, chociażby do eliminowania tzw. wąskich gardeł.
Integracja
Event Storming stanowi okazję do integracji zespołu poprzez wspólną naukę – oparty jest przecież przede wszystkim na rozmowie i zaangażowaniu wielu stron. A dla osób rozpoczynających pracę w danym projekcie, udział w sesji Event Stormingu może być jedną z metod wdrożenia projektowego.
Event Storming krok po kroku
W FIS-SST, w ramach zespołu R&D, przeprowadziliśmy własny warsztat Event Stormingu. Rozpoczęliśmy od przygotowania i wdrożenia - zapoznawaliśmy się zarówno z tematyką Event Stormingu, jak i z dobrymi praktykami tworzenia oprogramowania w ujęciu Domain-Driven Design. Po przeczytaniu szeregu długich artykułów, zapoznaniu się z książką twórcy Event Stormingu – Alberto Brandoliniego i obejrzeniu prezentacji z różnych konferencji programistycznych, w końcu przystąpiliśmy do dzieła! A zdobytą wiedzą i doświadczeniem dzielimy się dalej.
Jak rozpocząć warsztat?
Potrzebowaliśmy sporej ściany, papieru elektrostatycznego i różnokolorowych, elektrostatycznych karteczek. Krzesła porzuciliśmy przy biurkach – zgodnie z wytycznymi Event Stormingu, wszyscy uczestnicy muszą bowiem stać. Naszym zadaniem było zamodelowanie nowej aplikacji, programowanie której dopiero rozpoczniemy. Domeną, w ramach której działaliśmy był Handel Detaliczny.
Krok 1: Zdarzenia domenowe
Zdjęcie 1: Zdarzenia domenowe (na różowo) z informacjami dodatkowymi (na żółto)
Sercem warsztatu i punktem wyjścia dla całego tworzonego modelu biznesowego były zdarzenia domenowe. Musieliśmy zdefiniować czynności, które zachodzić mają w trakcie działania modelowanego oprogramowania.
Jakie wytyczne dają twórcy Event Stormingu względem zdarzeń domenowych? Zdarzenia mają być istotne z punktu widzenia ekspertów domenowych i wyrażone w czasie przeszłym.
Każdy z nas proponował zatem przykładowe zdarzenia. Krótko o nich dyskutowaliśmy. A następnie pomarańczowa kartka z zapisanym zdarzeniem trafiała na ścianę. Dla przykładu utworzyliśmy zdarzenia takie, jak: „Zautoryzowano użytkownika”, „Złożono zamówienie zewnętrzne”, czy „Zmieniono saldo”. Zdecydowaliśmy się na umiejscawianie zdarzeń na tablicy w kolejności ich występowania w programie – z końcem tego kroku uzyskaliśmy zatem swoistą „oś czasu” naszego programu. Na koniec przeprowadziliśmy weryfikację wsteczną – idąc od zdarzenia ostatniego do pierwszego, sprawdziliśmy, czy uwzględniliśmy wszystkie istotne zdarzenia domenowe. Przyszedł czas na dodanie komend.
Krok 2: Komendy
Zdjęcie 2: Komenda (na niebiesko) przypisana do zdarzenia
Musieliśmy się zastanowić jakie czynności prowadzą do wystąpienia ustalonych wcześniej zdarzeń. W efekcie, do większości zdarzeń przypisaliśmy niebieskie kartki z zapisanymi komendami. Zauważyliśmy, że w wielu przypadkach komendy były bardzo zbliżone do zdarzeń. I tak na przykład zdarzenie „Zautoryzowano użytkownika” połączyliśmy z komendą „Autoryzuj użytkownika”. Wiedzieliśmy, że za jakiś czas, już podczas developmentu, utworzone komendy staną się metodami, które napiszemy. Ale nie był to czas na myślenie o kodzie. Nie wiedzieliśmy jeszcze kto lub co odpowiada za wywołanie komend. Pora była to ustalić.
Krok 3: Aktorzy
Zdjęcie 3: Komenda (na niebiesko), z zaznaczonym aktorem - użytkownikiem
W najprostszym przypadku komenda inicjowana jest przez użytkownika i właśnie jego definiujemy wówczas jako aktora. Często już przy ustalaniu komend wiedzieliśmy, że aktorem jest użytkownik, zaznaczaliśmy to zatem na ścianie od razu.
Natomiast niektóre komendy stały się punktem wyjścia do wielu pytań o to, jak w ogóle ma działać projektowany przez nas program. Zastanawialiśmy się na przykład jak rozwiązać kwestię blokowania możliwości składania zamówień przez użytkownika. Blokadę inicjuje inne zdarzenie? Czy może upływ określonego interwału czasowego?
I tu należy pamiętać o wytycznych Event Stormingu dotyczących źródeł zdarzeń domenowych, a mianowicie: istnieje wiele różnych wyzwalaczy zdarzeń - może to być na przykład: komenda (np. pochodząca od użytkownika), system zewnętrzny, upływ czasu lub nawet inne zdarzenie domenowe.
Po uporaniu się z licznymi pytaniami nasza oś czasu była gotowa. Mogliśmy zatem już zdecydowanie skręcić w kierunku DDD i wyznaczyć agregaty.
Krok 4: Agregaty
Zdjęcie 4: Agregat (na zielono), ze zgrupowanymi przy nim zdarzeniami i komendami
W kolejnym kroku zniszczyliśmy naszą pieczołowicie tworzoną oś czasu! Kartki reprezentujące zdarzenia oraz związane z nimi komendy i aktorów pogrupowaliśmy tak, aby utworzyły agregaty.
Niektóre agregaty zidentyfikowaliśmy z łatwością – jak np. agregat „Użytkownik”. Na ścianę zawędrowała nowa, zielona kartka z takim właśnie napisem. A wszystkie elementy domenowo związane z użytkownikiem zgrupowaliśmy wokół niej.
Jednakże niektóre agregaty były nieco trudniejsze. I tak na przykład nowy agregat „Rozliczenie”, ze sporą ilością zgrupowanych przy nim kartek, rozbiliśmy na dwa osobne agregaty – „Rozliczenie użytkownika” i „Rozliczenie zamówienia”.
Przed nami był ostatni krok - ustalenie które agregaty są ze sobą powiązane i połączenie ich w tzw. Bounded Contexty.
Krok 5: Bounded Context
W Domain-Driven Design wskazuje się, że granice wspólnego języka („Ubiquitous Language”) są wyznacznikiem granic Bounded Contextów.
Jak powyższe przełożyć na praktykę? Za przykład weźmy domenę Handlu Detalicznego. Eksperci domenowi zajmujący się sprzedażą przypiszą produktowi pewien zestaw cech. Natomiast eksperci domenowi z dziedziny magazynowania i wysyłki produktów zainteresowani będą zupełnie innymi cechami produktu. Przez to eksperci techniczni, a w szczególności zespoły programistyczne, otrzymają dwie różne definicje produktu. Przy produkcie sprzedawanym istotnymi jego cechami będą np. cena i jej obniżki. Cechy te mogą być zupełnie nieistotne z punktu widzenia magazynowania i wysyłki, gdzie znaczącymi cechami produktu będą np. wymiary i przypisanie do konkretnego magazynu. Na bazie powyższego w kodzie utworzymy dwa osobne byty – np. SaleItem oraz InventoryItem. Mimo iż oba są przedmiotami, SaleItem oraz InventoryItem należeć będą do dwóch różnych kontekstów.
Jak zatem podeszliśmy do kwestii kontekstów podczas naszego warsztatu? Wbrew możliwym pierwszym skojarzeniom, wspomniane wcześniej „Rozliczenie użytkownika” i „Rozliczenie zamówienia” wcale nie znalazły się we wspólnym kontekście. „Rozliczenie użytkownika” przypisaliśmy do tego samego kontekstu, co samego „Użytkownika”. Kierowaliśmy się analogią bardzo zbliżoną do powyższego przykładu z przedmiotami.
Zdjęcie 5: Widok ściany pod koniec przeprowadzonego warsztatu
Czy to wszystko?
Zdecydowanie nie! Proces Event Stormingu może być znacznie bardziej złożony i zawierać dużo więcej kroków, w zależności od potrzeb konkretnego projektu. Nie istnieje również jedyna słuszna interpretacja zasad Event Stormingu – ważnym jest to, do czego prowadzi i kiedy może być przydatny.
Z Event Stormingu skorzystać można - podobnie jak my – do modelowania nowotworzonego oprogramowania. Ale sprawdzi się również dla oprogramowania legacy. Event Storming może być szczególnie przydatny w przypadku rozbudowanych, skomplikowanych aplikacji. A skupienie się na domenie w naturalny sposób prowadzić może do wdrożenia w projekcie zasad Domain-Driven Design.
Nam poprzez Event Storming udało się stworzyć nie tylko punkt wyjścia dla prac programistycznych nad naszą nową aplikacją. Upewniliśmy się, że wszyscy w ten sam sposób rozumiemy jej zakres, schemat działania i zawarte w niej funkcjonalności – czyli zgodnie z cytatem rozpoczynającym ten artykuł rzeczywiście okazało się, że „in any Event Storming session of all different kinds, everyone knows what everyone else knows“.