Jak to zrobić technicznie napisali koledzy wyżej. Ja tylko przyczepię się szczegółu w jaki sposób zamodelowałeś ten proces w kodzie. Otóż z tego co opisałeś, to powinieneś mieć jeden moduł UserRegistration
, który ma w sobie logikę rejestracji użytkownika i wysyłania powiadomienia za pomocą wstrzykiwalnego serwisu SmtpService
który odpowiada za komunikację z serwerem SMTP i nie ma żadnej logiki biznesowej, tak jak przykładowo metoda Save
jakiegoś repozytorium, która dostaje obiekt i jedynym jej zadaniem jest utrwalić ten obiekt w storage. Nie powinieneś mieć dwóch osobnych modułów w tym kształcie, bo twój moduł powiadomień jest biznesowo związany z rejestracją użytkownika - tworzy link weryfikacyjny, aktywuje użytkownika, itd. Jak coś zmienisz w jednym module to musisz automatycznie poprawiać w drugim.
Sam fakt tego, że wstrzykujesz jeden moduł do drugiego już wskazuje na zły podział odpowiedzialności. Moduły powinny być od siebie jak najbardziej niezależne. Co ci z modularności jak przy każdej zmianie będziesz musiał zmieniać trzy inne moduły? Co daje taka separacja? Nie mówiąc o tym, że wraz z rozwojem systemu będziesz dodawał kolejne typy powiadomień i w ten oto sposób moduł notyfikacji stanie się sercem twojej aplikacji bo wszystkie inne moduły będą miały do niego zależność, a to bardzo złe jest.
To co zrobiłeś to przeciwieństwo package by feature, bo feature w nazwie to wymaganie biznesowe/use case/przypadek użycia i tak powinieneś dzielić kod. Czyli UserRegistration
, UserProfileUpdate
, AccountSupsension
, itd.
Jak to zrobić technicznie napisali koledzy wyżej. Ja tylko przyczepię się szczegółu w jaki sposób zamodelowałeś ten proces w kodzie. Otóż z tego co opisałeś, to powinieneś mieć jeden moduł UserRegistration
, który ma w sobie logikę rejestracji użytkownika i wysyłania powiadomienia za pomocą wstrzykiwalnego serwisu SmtpService
który odpowiada za komunikację z serwerem SMTP i nie ma żadnej logiki biznesowej, tak jak przykładowo metoda Save
jakiegoś repozytorium, która dostaje obiekt i jedynym jej zadaniem jest utrwalić ten obiekt w storage. Nie powinieneś mieć dwóch osobnych modułów w tym kształcie, bo twój moduł powiadomień jest biznesowo związany z rejestracją użytkownika - tworzy link weryfikacyjny, aktywuje użytkownika, itd. Jak coś zmienisz w jednym module to musisz automatycznie poprawiać w drugim.
Sam fakt tego, że wstrzykujesz jeden moduł do drugiego już wskazuje na zły podział odpowiedzialności. Moduły powinny być od siebie jak najbardziej niezależne. Co ci z modularności jak przy każdej zmianie będziesz musiał zmieniać trzy inne moduły? Co daje taka separacja? Nie mówiąc o tym, że wraz z rozwojem systemu będziesz dodawał kolejne typy powiadomień i w ten oto sposób moduł notyfikacji stanie się sercem twojej aplikacji bo wszystkie inne moduły będą miały do niego zależność, a to bardzo złe jest.
To co zrobiłeś to przeciwieństwo package by feature, bo feature w nazwie to wymaganie biznesowe/use case/przypadek użycia i tak powinieneś dzielić kod. Czyli UserRegistration
, UserProfileUpdate
, AccountSupsension
, itd.
Jak to zrobić technicznie napisali koledzy wyżej. Ja tylko przyczepię się szczegółu w jaki sposób zamodelowałeś ten proces w kodzie. Otóż z tego co opisałeś, to powinieneś mieć jeden moduł UserRegistration
, który ma w sobie logikę rejestracji użytkownika i wysyłania powiadomienia za pomocą wstrzykiwalnego serwisu SmtpService
który odpowiada za komunikację z serwerem SMTP i nie ma żadnej logiki biznesowej, tak jak przykładowo metoda Save
jakiegoś repozytorium, która dostaje obiekt i jedynym jej zadaniem jest utrwalić ten obiekt w storage. Nie powinieneś mieć dwóch osobnych modułów w tym kształcie, bo twój moduł powiadomień jest biznesowo związany z rejestracją użytkownika - tworzy link weryfikacyjny, aktywuje użytkownika, itd. Jak coś zmienisz w jednym module to musisz automatycznie poprawiać w drugim.
Sam fakt tego, że wstrzykujesz jeden moduł do drugiego już wskazuje na zły podział odpowiedzialności. Moduły powinny być od siebie jak najbardziej niezależne. Co ci z modularności jak przy każdej zmianie będziesz musiał zmieniać trzy inne moduły? Co daje taka separacja? Nie mówiąc o tym, że wraz z rozwojem systemu będziesz dodawał kolejne typy powiadomień i w ten oto sposób moduł notyfikacji stanie się sercem twojej aplikacji bo wszystkie inne moduły będą miały do niego zależność, a to bardzo złe jest.
To co zrobiłeś to przeciwieństwo package by feature, bo feature w nazwie to wymaganie biznesowe/use case/przypadek użycia i tak powinieneś dzielić kod. Czyli UserRegistration
, UserProfileUpdate
, AccountSupsension
, itd.
@markone_dev:
Tak wygląda struktura mojego modułu, publiczna jest tylko fasada. Wszystko co związane z operacjami na koncie użytkownika jest w tym module, cała rejestracja, po zmianę hasła, nadanie użytkownikowi nowego uprawnienia itp. Za wysyłkę linku aktywacyjnego mam moduł Notification i tam klasę do zbudowania linku aktywacyjnego dla rejestracji. I mam tak jak mówisz, że do UserRegistration powinien być wstrzyknięty jakiś SMTP service. U mnie to jest NotificationFacade wstrzyknięte do UserRegistration. VerificationRegistration jest wstrzyknięte do UserRegistration, bo w VerificationRegistration mam cały proces tworzenia token i jego potwierdzenia. Nie pomyślałem właśnie wcale, że co będzie jak dojdą mi kolejne powiadomienia z jakiś innych modułów i będę musiał to wstrzykiwać wszędzie i zrobi się spaghetti i nic mi po tej modularności.
Może zrobię package Notification w tym swoim module User i tam zajmę się cała operacją tworzenia tego tokena i wysyłki, a w pakiecie infrastructure ogarnę cała integrację z tym API SMTP i konfigurację, co o tym myślisz?
Będzie to wtedy zamknięte w obrębie jednego modułu.
Doszedłem jeszcze do jednego wniosku, nie wiem czy poprawnego, że trochę te moje testy jednostkowe w pamięci zaczynają się robić kulą u nogi w moim projekcie. Bo mam teraz proces rejestracji użytkownika i on składa się z kilku mniejszych procesów, jak zapis użytkownika do bazki, stworzenie tokena i wysłanie powiadomienia z linkiem weryfikacyjnym, ale teraz myślę, że to nie jest jakaś skomplikowana logika biznesowa na potrzeby testów jednostkowych. I tak jak pierwsze dwa procesy mogłem przetestować bez problemu tak już do wysyłki emali potrzebuje jakiegoś TestContainers czy czegoś innego co mogłoby mi zasymulować wysyłkę emaila dla potrzeb testu.
Myślę, że tutaj sprawdzą jest bardziej testy integracyjne albo E2E.
Dzięki wszystkim za cenne wskazówki!