Jak dobrze podzielić aplikację na moduły

0

Powiedzmy, że mamy dwa moduły: Ordering i Products (wiem, oklepana domena, ale po co szukać innej, jak nawet tej się nie umie dobrze zrobić...).

Moduł Ordering potrzebuje danych z modułu Products do jakiejś swojej logiki biznesowej (np. nie można dodać nieaktywnego produktu do zamówienia). Standardowym rozwiązaniem jest w takim przypadku emitowanie z modułu Products eventu zawierającego ProductId i IsActive. Moduł Ordering nasłuchuje na ten event, aktualizuje swoje dane i wszystko ładnie działa - nie musi odpytywać modułu Products, żeby sprawdzić, czy produkt jest aktywny.

Po jakimś czasie pojawia się kolejne wymaganie: jeśli zamówienie zawiera produkt z grupy lub podgrupy X, wtedy zamówienie nie może zostać normalnie kontynuowane, tylko osoba Y musi dodatkowo zrobić Z. Żeby nie odpytywać modułu Products, moduł Ordering zawiera teraz dodatkowo hierarchię grup produktów aktualizowaną przez eventy z modułu Products.

Czas mija i pojawia się kolejne wymaganie. Otóż produkt może mieć coś takiego jak dopłaty (np. przedłużenie jakiegoś tam kabla wchodzącego w skład produktu). W Ordering chcemy, żeby można było takie dopłaty wiązać z pozycjami zamówień. A czego potrzebujemy, by sprawdzić, czy daną dopłatę można powiązać z danym produktem? Oczywiście danych z modułu Products.

Już chyba wiadomo, do czego zmierzam: wraz ze wzrostem złożoności systemu moduły potrzebują coraz więcej swoich wewnętrznych danych. Możemy te dane kopiować, tylko czy ma to sens? Czy Ordering ma mieć wszystkie dane z Products skopiowane u siebie, żeby móc pełnić swoją funkcję? Co na ten temat sądzicie? Niezależność modułów to fikcja?

8

Moduł Ordering nasłuchuje na ten event, aktualizuje swoje dane i wszystko ładnie działa - nie musi odpytywać modułu Products, żeby sprawdzić, czy produkt jest aktywny.

Czyli co w Module Ordering chcesz robić kopię bazy Products?
Bez sensu!

I jakie eventy? Po co to? Informacja o produkcie niech będzie statyczna w bazie danych, a podczas tworzenia zamówienia moduł Ordering sam odpyta moduł Products o dostępność i ewentualne możliwe kombinacje produktów. Po co na próżno mają jakieś eventy latać i po co robić redundancje informacji.
Generalnie mieszasz funkcjonalności modułów ze strukturami danych na których te moduły pracują.

Czy Ordering ma mieć wszystkie dane z Products skopiowane u siebie, żeby móc pełnić swoją funkcję? Co na ten temat sądzicie? Niezależność modułów to fikcja?
Nie na tym polega modułowość, żeby każdy moduł był samodzielną aplikacją.

1

@nobody01: A czym jest moduł? Moduł: must be independent and interchangeable and must have everything necessary to provide desired functionality?

Oczywiście, że ma być niezależny i musi mieć wszystko co potrzebne ale Ty zakładasz, że sprzedawca zestawu kluczy do samochodu ma dodać Ci do tego zestawu samochód bo przecież bez samochodu nie będziesz miał nad czym tymi kluczami pracować.

Moduł zamówień z samymi produktami może być powiązany jedynie jakimiś identyfikatorami i tyle... Zamówienie to lista identyfikatorów produktów a nie całe produkty skopiowane do zamówienia.

0

To po co w takim razie są te wszystkie eventy, brokery, skoro i tak koniec końców moduły / mikroserwisy są od siebie zależne? Żeby móc wykonać jakąś operację asynchronicznie? Tylko po to?

0

@nobody01: struktura i sposób poukładania danych w systemie to jedno, komunikacja pomiędzy pracującymi modułami to drugia, a asynchroniczne wykonywanie operacji to rzecz trzecia i są to narzędzia / składniki systemu, które poukładane i wykorzystywane w odpowiedni oraz zaplanowany sposób tworzą spójny działający system.

Eventy to eventy a dane to dane. Oczywiście wraz z eventem mogą być przesyłane dane ale to jakie dane ile i po co wynika z architektury i budowy całego systemu.

0

To jest trochę pytanie, co wybrać: direct call czy messaging do komunikacji. Sens wydaje się mieć używanie direct call do pobierania danych (np. moduł B potrzebuje danych z modułu A, żeby zrealizować jakiś swój wewnętrzny proces, więc odpytuje API modułu A) i messaging, gdy np. jakiś proces z modułu B wymaga zainicjowania innego procesu w module A (moduł B wysyła event, na który odpowiada moduł A).

3
nobody01 napisał(a):

To po co w takim razie są te wszystkie eventy, brokery, skoro i tak koniec końców moduły / mikroserwisy są od siebie zależne? Żeby móc wykonać jakąś operację asynchronicznie? Tylko po to?

Ja to widzę tak, że gdy już użytkownik wybierze produkty i za nie zapłaci, to moduł Ordering wysyła event OrderCompleted, a event ten jest odbierany przez: Invoicing do wystawienia faktury, Delivery do spakowania i wysłania i DataAnalytics do zebrania informacji o najczęściej kupowanych razem produktach i skuteczniejszych podpowiedzi w przyszłości, oraz inne moduły.

No, ale ja nie jestem architektem, nie znam się na kopiowaniu baz przez eventy, może tak trzeba. Ale ja jednak wolę mieć jedno źródło prawdy.

0

@somekind: W ogóle żadnych danych bys nie kopiował przez eventy?

4

nobody01 przede wszystkim podejście zależy od tego czy to jest modularny monolit (i wtedy dane lecą często w RAMie przez jakiś EventBus) czy to są inne aplikacje (czyli moduł = aplikacja)

0

@ProgScibi: A w tym drugim przypadku jak byś postąpił?

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0