Walidacja w serwisie czy w repozytorium

Odpowiedz Nowy wątek
2019-02-11 13:23
0

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?

edytowany 1x, ostatnio: Tyvrel, 2019-02-11 14:05

Pozostało 580 znaków

2019-02-14 14:40
0

Chyba trochę za bardzo rozdrabniasz tej problem. Twój kod (np. serwis używający obiektu repozytorium) nie powinien wiedzieć jakie constrainty są sprawdzane niżej, to prawda. Tak samo jak repo nie powinno wiedzieć jakie constrainty ma baza danych. Ale nie znaczy to że z tego powodu powinieneś to wszystko sprawdzać w kodzie, ponieważ TY- programista projektujący daną aplikacje WIESZ co, gdzie i jak jest sprawdzane.


Na każdy złożony problem istnieje rozwiązanie które jest proste, szybkie i błędne.

Pozostało 580 znaków

2019-02-15 04:43
0

To, co pisze @Aventus nie jest do końca prawdą. Brzmi to tak jakby mylił constrain z walidacją ale mogę się mylić.

Nie do końca rozumiem o co ci chodzi, pewnie masz jakieś złe założenie odnośnie modelu.

Ale jeśli chodzi ci o walidację poza warstwą aplikacyjną:

To, że spełniasz constrain encji nie musi znaczyć, że cała encja jest prawidłowa dlatego często stosuje się sepecyfikator, który można utożsamiać z "walidacją tą niżej". Poza tym również możesz się spotkać z sytuacją, kiedy trzeba z walidować kompozycje obiektów, a takie rzeczy robi się w serwisie domenowym, fabryce. Jak byś się uparł to możesz to wsadzić do repozytorium, ale to tak jak byś budował piwnicę pod dachem, czyli trochę bez sensu.

Pozostało 580 znaków

2019-02-19 13:58
2

A to nie jest tak ze są dwie osobne walidacje?
Na poziomie logiki biznesowej walidowane są założenia biznesowe, a na poziomie bazy danych są walidowane jakieś constrainty bazodanowe.

BTW. To co Ty nazywasz repozytorium to bardziej connector/adapter do bazy danych.


:D

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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