niedziela, 9 października 2011

Konferencja Warsjawa - kolejny warsztat DDD&CqRS Leaven

Zapraszam na konferencję Warsjawa, która odbędzie się w najbliższą sobotę (15 października) w Warszawie.

Warto dodać, że konferencja jest całkowicie darmowa:)

Podczas konferencji będziecie mogli uczestniczyć między innymi w naszych warsztatach, poświęconych projektowi DDD&CqRS Leaven.

Szczegółowy program warsztatów: https://github.com/warszawajug/warsjawa2011/wiki/Warsztaty-DDD-i-CqRS.

środa, 5 października 2011

Persystentny Multi-Listener, czyli... Saga

Persystentny multi-listener... jak to pięknie brzmi...:)

Cóż to takiego?

Listener - czy obiekt słuchający zdarzeń,
mulit - czyli chodzi o wiele zdarzeń,
persystentny - czyli posiadający trwały stan.


Podczas ostatnich warsztatów z zakresu projektu DDD-CqRS Leaven wspomniana wyżej technika modelowania czasu spotkała się z zainteresowaniem wielu osób. Nic dziwnego, jest to dosyć nowy pattern; również na szkoleniach wzbudza zawsze największe emocje. Głównie dlatego, że ciężko pogodzić się z myślą, że coś tak złożonego można modelować i implementować w tak prosty i przyjemny sposób:P

Pattern ma swoją oficjalną nazwę, brzmi ona Saga. Jeżeli saga kojarzy się senior developerom z sagą rodziny Carringtonów, to dobrze się Wam kojarzy. Saga to coś co może rozciągać się w czasie niczym telenowela. Saga jest patternem służącym do orkiestracji wielu zdarzeń, które mogą zajść w rozproszonym systemie w nieokreślonej kolejności. Czas pomiędzy zajściem zdarzeń może być relatywnie długi, dlatego należy persystować jej stan w czasie oczekiwania na kolejne zdarzenie.

Przykład:
Wyobraźmy sobie system, w którym mamy moduły: sprzedaży, płatności i magazynu.
W module sprzedaży możemy zatwierdzić obiekt biznesowy Zamówienie. Zamówienie rzuca wówczas zdarzenie biznesowe ZatwierdzonoMnie zawierające id tegoż zamówienia.
W module płatności możemy dokonać wpłaty. Być może jest to przedpłata dokonana wcześniej niż zatwierdzenie zamówienia... Moduł ten rzuca zdarzenie niosące informację o zajściu faktu dokonania wpłaty.
Oba zdarzenia są orkiestrowane przez sagę Zakupy. Jeżeli otrzyma ona oba zdarzenia (pasujące po id biznesowym) i stwierdzi, że jesteśmy "kwita" wówczas może wysłać sygnał do modułu magazynowego aby przygotować paczkę do wysyłki.

Oczywiście możemy tego typu proces zaimplementować w inny sposób niż zdarzeniowy, ale jeżeli zależy nam na decouplingu modułów systemu (wraz z wszystkimi konsekwencjami: skalowanie, testowanie, rozszerzalność, otwartość na dodawanie pluginów, redukcja architektury Speaghetti na poziomie modułów) to warto posłużyć się Sagą.


Udi Dahan dosyć dobrze wyjaśnia motywację oraz szczegóły koncepcyjne: Saga Persistence and Event-Driven Architectures dlatego nie chcę powtarzać, tego co zostało napisane ponad 2 lata temu.

Jak widać w powyższym linku technicznie Saga to złożenie 2 wzorców: Observer i Memento. O ile observera każdy zna choćby z bibliotek graficznych i wszechobecnych tam onClickListenerów, o tyle Memento jest mniej znanym patternem. Jeżeli ktoś oglądał film pt. Memento o człowieku, który miał problem z transferem danych z pamięci podręcznej (kora przed-czołowa) do pamięci długotrwałej (hipokamp) to skojarzenie jest również poprawne. Memento to pattern służący obiektom na wysyłanie do siebie informacji na przyszłość. Tak jak bohater filmu, który zapisywał i tatuował sobie na rękach informacje o tym co należy zrobić w przyszłości:)

Natomiast zainteresowanych szczegółami implementacji Sagi odsyłam do przykładu w projekcie DDD&CqRS Leaven:



//=============================================

Jako ciekawostkę dodam, że niektóre szyny komunikatów w .NET wspierają mechanizm Sagi niejako "z pudełka"...
Techniczny komunikat (message) jest traktowany na poziomie logicznym jak zdarzenie (event). Ichnie "Message Driven Beany" reagaujące na wiele zdarzeń to po prostu Sagi. Do tego automatyczne ładowanie i zapisywanie Memento, kończenie albo usypianie sagi oraz drobny szczegół: obsługa współbieżności...
Natomiast my w swym świecie Javy wciąż szukamy uber-frameworka webowego, który daje złudzenie, że każdy system jest CRUDem...