I teraz możemy podejść do tego tak że w serwisie walidujemy return filters.isEmpty() ? dao.fetchWithoutFilters(filters) : dao.fetchWithFilters()
.
To nie jest "walidacja", tylko po prostu obsłużenie obu możliwości (jako poprawnych).
Swoją drogą przykład wygląda na błędny, powinno chyba być odwrotnie: dao.fetchWithoutFilters() : dao.fetchWithFilters(filters)
.
Aczkolwiek jeśli brak filtrów jest poprawny (na zasadzie *.*), to spodziewałbym się, że powinna go obsłużyć jedna metoda fetchWithFilters
, i nie potrzeba robić osobnej fetchWithoutFilters
. Tak samo jak nie ma potrzeby, żeby obok println(string)
była osobna printEmptyLn()
, jeżeli println
może "wydrukować" pustego stringa i nic złego się przez to nie dzieje.
W (standardowej) Javie nie ma typów kolekcji, które by gwarantowały, na poziomie samego typu, że nie są puste. Jeśli jakaś metoda przyjmuje zatem kolekcję, to powinna ją obsłużyć bez względu na liczbę elementów.
Jeśli natomiast brak filtrów jest nieprawidłowy z zasady, to stworzyłbym klasę Filters
, która byłaby opakowaniem na mapę, ale nie można by stworzyć obiektu Filters
, który nie zawierałby żadnych danych. Inaczej mówiąc, obiekt Filters
zawierający pustą mapę to jest coś, co fizycznie nie ma prawa zaistnieć.
A wtedy nie ma dylematów dotyczących tego, "gdzie zwalidować mapę", która (jeśli tego nie zrobimy) porusza się po naszym kodzie z taką jakby niewidzialną właściwością - czy jestem już zwalidowana, czy nie jestem? Której jednak nie widać, i nie można jej łatwo sprawdzić.
Naturalnym miejscem walidacji staje się to, i tylko to miejsce, w którym tworzona jest instancja Filters
. I można je łatwo znaleźć w kodzie - po prostu wyszukując, gdzie obiekty Filters
są instancjonowane.
musimy gdzieś założyć że to co wchodzi jest bez błędów.
To właśnie będzie owo "gdzieś". Granica, w której anonimowa mapa, sama z siebie nie gwarantująca dotrzymania żadnego kontraktu, przeistacza się w nasz obiekt domenowy, nad którego kontraktem mamy kontrolę.