Czy klasy typu DTO powinny mieć metody?

0

Cześć,
Do tej pory spotkałem się w mojej dość skromnej karierze z klasami DTO posiadającymi jedynie pola które są w danym przypadku potrzebne. Np. Na jakiś widok z listą obiektów potrzebujemy jedynie podzbiór pól klasy modelu dziedziny. Zastanawia mnie fakt czy takie obiekty DTO powinny mieć jakieś metody. Jeśli tak, to jakiego typu.
Mamy załóżmy klasę OpeningHoursDTO, która zawiera godziny otwarcia w poszczególnych dniach. Wszystkie pola są jako string. Wiec czy metoda typu "IsValid()" która by sprawdzała, czy wszystkie stringi mają odpowiednią wartość, mogła by znajdować się w tej klasie DTO?

2

Raczej nie powinny. DTOsy często są poddawane serializacji i to jest 1 problem. Metody takie jak IsValid czy displayInMyFancyFormat mogłyby być zwykłymi polami o typach odpowiednio bool i string.

3

DTO służy wyłącznie jako pojemnik na dane do przesłania gdzieś, a więc żadna metoda takiej klasy nigdy nie zostanie wywołana. Więc po co ma istnieć?

2

DTO ma być głupi jak cep

10

Czy w DTO można umieszczać dowolne metody?
bosak.jpg

2

Ja bym zadał inaczej pytanie, a mianowicie Czy String jest DTO?

3

Imo DTOsy mogą mieć jakieś takie metody "pomocnicze" które tylko odczytują parametry. Np isFinished() zamiast za każdym razem wyciągać z DTO stan i porównywać go do jakiegoś.

0

@AnyKtokolwiek:

Wszystkie pola są jako string" mam mocne wątpliwości.

A czy jeśli DTO ma założy same pola typu string to jest coś nie tak? Załóżmy że mamy klasę DTO z polami Imie, Nazwisko, Miasto, Ulica. Wszystko jako string. Co w takim wypadku jest źle? Może popełniam jakiś błąd którego nie zauważam.

1

@Kordoba: na poziomie DTO takie pola moga mieć sens jako String, ale do daty/godziny to już średnio - to powinno być jako Date . A na poziomie domeny aplikacji operowałbym klasami jak City albo Name (ewentualnie typealiasami).

3

Dopuszczam metody pomocnicze, które ułatwiają chodzenie po strukturach danych, ale bez logiki biznesowej.

Odnośnie isValid() - jeśli to jest walidacja strukturalna w stylu „string nie dłuższy niż” np. na DTO reprezentującym dane przychodzące w requescie HTTP, to pewnie jeszcze ujdzie - chociaż tutaj możesz użyć adnotacji i mieć to ogarnięte niejako z automatu.

0
Charles_Ray napisał(a):

Dopuszczam metody pomocnicze, które ułatwiają chodzenie po strukturach danych, ale bez logiki biznesowej.

Odnośnie isValid() - jeśli to jest walidacja strukturalna w stylu „string nie dłuższy niż” np. na DTO reprezentującym dane przychodzące w requescie HTTP, to pewnie jeszcze ujdzie - chociaż tutaj możesz użyć adnotacji i mieć to ogarnięte niejako z automatu.

Adnotacyjna walidacja mocno zaniedbuje związki miedzy polami, np "jeśli płeć to PESEL" itd. Nawiasem mówiąc idą nowości zwane "class level validation", ale jeszcze nie czytałem, zrobiony koło tego IT-marketing świadczy, ze branża się przyznaje do zaniedbania.

Zanim to nastąpi / mimo że to nastąpi, metody walidacyjne mogą mieć sens. Ja bym dawał takie metody chętnie.
Oczywiście metody, (jakby się to w C++ wyrażało). z atrybutem const, nie zmieniające stanu.

piotrevic napisał(a):

Raczej nie powinny. DTOsy często są poddawane serializacji i to jest 1 problem. Metody takie jak IsValid czy displayInMyFancyFormat mogłyby być zwykłymi polami o typach odpowiednio bool i string.

Nie spotkałem się, aby profesjonalne rozwiązanie serializacyjne miało z tym kłopoty- choć wiem, o czym mówisz i jakaś ręczna robótka może wleźć na taki problem.
I jednak AKTYWNA metoda, a nie MARTWE pole, które może mieć fałszywą wartość.

0

Jak dla mnie DTO powinno mieć same pola, walidacja juz w pewien sposob narusza tę zasadę.
Co w przypadku gdy obiekt jest poprawny zależnie od kontekstu w jakim jest użyty albo od innych danych zawartych w modelu? Czy to juz nie bedzie wchodzić w logike biznesową? Np jeśli osoba fizyczna to model musi zawierać pesel, jeżeli osoba prawna to nip? W tej sytuacji isValid może sprawdząc częściową poprawność danych jak np czy dane są w odpowiednim formacie itp. tylko czy w tej sytuacji ma to sens?

0

Ludzie, przecież walidacja „czy string jest liczbą” to nie jest jedyna walidacja jaką robicie w aplikacji.

0
xxx_xx_x napisał(a):

Jak dla mnie DTO powinno mieć same pola, walidacja juz w pewien sposob narusza tę zasadę.

Co w przypadku gdy obiekt jest poprawny zależnie od kontekstu w jakim jest użyty albo od innych danych zawartych w modelu? Czy to juz nie bedzie wchodzić w logike biznesową? Np jeśli osoba fizyczna to model musi zawierać pesel, jeżeli osoba prawna to nip? W tej sytuacji isValid może sprawdząc częściową poprawność danych jak np czy dane są w odpowiednim formacie itp. tylko czy w tej sytuacji ma to sens?

W ogóle istnienie isValid nie ma żadnego sensu, bo to jest skrajnie bezużyteczna rzecz. Coś się zepsuło, ale nie wiadomo co, gdzie i dlaczego.

Trzeba mieć bardziej wyrafinowane rozwiązanie, które umie zebrać informacje o wszystkich błędach we wszystkich polach danego DTO, i zwrócić je do użytkownika z jakimiś czytelnymi komunikatami błędów, które z kolei mogą być lokalizowane, zawierać dodatkowe kody błędów, a na pewno przynajmniej informacje o wprowadzonej i oczekiwanej wartości.
No i oczywiście można pisać takie coś samemu, i wklejać do DTO (każdego oddzielnie?), sprawiając ze już nie będą POXO i po prostu będą brzydkie.
To chyba jednak lepiej użyć jakiejś biblioteki do walidacji, co daje też tę zaletę, że biblioteki zazwyczaj wymagają sensownego podejścia, czyli odseparowania DTO od reguł walidacji.

0

A propos walidacji.
Od zawsze (odkąd realnie uprawiam OOP) i już do śmierci mój sprzeciw będzie budzić wielokrotne robienie kodu walidujacego, czy odnośnie backendu/frontu javascriptowego, czy wielowarstwowej Javy.
"nawet" jeśli przy pierwszym tworzeniu projektu to się uda, to 99.99% polegnie przy utrzymaniu i rozwoju. Rozbieżności są gwarantowane.

Ilustracja z realnego życia: duży sklep utracił moją firmę jako klienta. Frontowa formatka rejestracyjna na ok 10 pól, imię nie jest obowiązkowe, button OK. Z MySQL-a leci wyjątek ujawniający strukturę tabeli czepiający się imienia, po czym (powszechna egzotyka) następny radosny mesage "informacje zapisane poprawnie". Konta nie da się użyć, bo nie, założyć nowego tez nie, bo NIP. Pewnie do dziś i leżą sprzeczne dane.

W tym patrzeniu każda a) jednolita przez wszystkie warstwy b) decydująca walidacja jest na wagę złota. Prędzej frontowiec javowski wzrokowo / transpiler / framework frontowy skorzysta z wiedzy walidacyjnej w klasie DTO, niż gdy jej nie będzie wcale

1
AnyKtokolwiek napisał(a):

W tym patrzeniu każda a) jednolita przez wszystkie warstwy b) decydująca walidacja jest na wagę złota. Prędzej frontowiec javowski wzrokowo / transpiler / framework frontowy skorzysta z wiedzy walidacyjnej w klasie DTO, niż gdy jej nie będzie wcale

Ja rozumiem, żeby frontend generował sobie walidację na podstawie jakiegoś OpenAPI, ale proponować frontend zależny od kodu backendowego w 2020?!

1

Jak walidacja jest związana z formatem przesyłu danych{JSON, XML} Schema, to tak. W innym wypadku to nie ma sensu: co jak ktoś użyje twoich klas DTO w inny sposób? Każda dodatkowa walidacja to wpychanie dodatkowej wiedzy biznesowej

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