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?