Ostatnio dręczy mnie jedno pytanie: Czy walidacja
powinna być wykonywana w serwisie
, czy w repozytorium
.
Serwis
Większość osób, które o to pytałem, odpowiadała bez wahania: w serwisie
, przecież to część logiki biznesowej. Kto to widział, żeby logika biznesowa siedziała w repozytorium!
No ale co na to wszędobylskie constrainty typu UNIQUE
czy NOTNULL
(masa innych CHECK
)? Przecież to walidacja w najczystszej formie i to po stronie repozytorum
(a nawet jeszcze głębiej).
Jeśli po stronie serwisu
, to wypadałoby wywalić wszystkie constrainty. To natomiast wiąże się z wyjątkowo woooooolną
walidacją (z mnóstwem dodatkowych zapytań do bazy danych)
transaction()
.filter(() -> repository.existsByX(entity.getX)) //X to unique property
.filter(() -> ...)
.filter(() -> ...)
.peek(() -> repository.save(entity));
Repozytorium
Jeśli natomiast walidujemy w repozytorum
, jest to umieszczanie tam logiki biznesowej, która czasami może być naprawdę pooookaźna
. Podmieniając takie repozytorium
na inną implementację trzebaby wiedzieć, że ową walidację trzeba dodatkowo zaimplementować (a to constraintem na bazie, a to jakimiś ifami
).
Troche tu, troche tam
Trzecie rozwiązanie: troche tu, troche tam? Dla mnie osobiście brzmi to jak rak
, który jest nieutrzymywalny. Jedna odpowiedzialność podzielona nie dość, że na dwa komponenty, to jeszcze takie, które znajdują się w różnych warstwach.
Mimo to zazwyczaj widzę, że większość walidacji jest w serwisie
, natomiast część (np. UNIQUE
) w repozytorium i tego już serwis nie sprawdza.
No i teraz pytanie: zmieniam repozytorium
(bazę danych) na takie, które nie obsługuje constraintów UNIQUE
. Muszę dodać walidację albo w serwisie
, albo w repozytorium
.
Albo zmieniam repozytorium
(bazę danych) z takiego, które nie obsługuje UNIQUE
do takiej, która obsługuje. Musze wtedy zmienić również serwis
, bo przecież trzeba wyrzucić niepotrzebne, wolne sprawdzenie na UNIQUE
. Trzeba się mocno pilnować co dany zespół komponentów robi i synchronizować to przy każdej zmianie.
Działając w warstwie repozytorium
musze modyfikować warstwę wyżej. Abstrakcja, nie cieknie przez palce. Ona się przelewa
!
Co wy na to?