Mapowanie w DTO vs dedykowany mapper

Mapowanie w DTO vs dedykowany mapper
MY
  • Rejestracja:około 5 lat
  • Ostatnio:5 miesięcy
  • Postów:24
0

Cześć,
mając prostą sytuację, w której jestem w stanie mapować DTO na jakiś obiekt domenowy często robię to bezpośrednio w nim dodając metodę:

Kopiuj
class CarRequest {
[...]
Car toCar() ...
}

Dzięki temu nie muszę nawet udostępniać getterów, bo ich nie potrzebuję.

Czasami jest tak, że do mapowania potrzebuję więcej informacji - np. jakiegoś propsa, albo wyliczenia jakiejś wartości. Mogę to robić przez przekazanie dodatkowych parametrów do funkcji getCar() albo wyniesienia mapowania do dedykowanego serwisu. Próbowałem znaleźć coś na ten temat od kogoś z większym doświadczeniem - kiedy stosować które podejście, czy warto być spójnym w projekcie, czy wynosić do mappera w jakimś konkretnym momencie. Kojarzycie? Albo możecie coś o tym powiedzieć?

Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

To jakiś niezły fikołek :D Konwertowanie z obiektu domenowego na DTO w ten sposób sie spotyka, ale w drugą stronę to juz trochę ciężej. Ja bym zrobił jakś osobny serwis który zajmuje się taką konwersją.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
MY
  • Rejestracja:około 5 lat
  • Ostatnio:5 miesięcy
  • Postów:24
1
Shalom napisał(a):

To jakiś niezły fikołek :D Konwertowanie z obiektu domenowego na DTO w ten sposób sie spotyka, ale w drugą stronę to juz trochę ciężej.

Ale jak w drugą stronę? Że w obiekcie domenowym toResponse()? Wtedy mamy zależność domeny od infrastruktury, co raczej nie jest dobrym patternem

Shalom napisał(a):

Ja bym zrobił jakś osobny serwis który zajmuje się taką konwersją.

No jasne, pytanie czy zawsze warto - jeśli np. mapowanie to jest po prostu przepisanie pól

Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

Wtedy mamy zależność domeny od infrastruktury, co raczej nie jest dobrym patternem

? Masz tylko zależność od DTO bo przecież konkwertujesz sobie to na jakieś DTO. Nie widzę tu żadnej infrastruktury. Co więcej trudno mi sobie wyobrazić to co opisałeś bo u mnie DTO to są DTO i zwykle leżą w module razem z klientem tak zeby ktoś mógł łatwo tego serwisu uzywać. Dodanie tam zależności do domeny to jakiś hardkor. Ktoś kto chce używać serwisu potrzebuje znać endpointy + jak zmapować odpowiedź na jakieś DTO. W efekcie client nie powinien zawierać nic więcej zeby był lekki.

No jasne, pytanie czy zawsze warto - jeśli np. mapowanie to jest po prostu przepisanie pól

Jeśli tak jest to piszesz CRUDa i w ogóle nie masz obiektów domenowych tylko się okłamujesz i mapujesz DTO na inne DTO (anemic domain model)


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 4x, ostatnio: Shalom
MY
  • Rejestracja:około 5 lat
  • Ostatnio:5 miesięcy
  • Postów:24
0

@Shalom:

? Masz tylko zależność od DTO bo przecież konkwertujesz sobie to na jakieś DTO. Nie widzę tu żadnej infrastruktury. Zresztą chcesz przecież zrobić identyczną zależność, dodając w twoim obiecie domenowym fromDTO ;)

Dobra dobra, spróbuję uściślić :) Albo najlepiej dać konkretny przykład:
Mam sobie endpoint, który przyjmuje zamówienie na samochód:

Kopiuj
class CarRestRequest(val color: String, val seats: Int)

Z drugiej strony zamówienia na samochody dostaję z jakiegoś pliku, który sobie wczytuję (nie mam tam ilości miejsc, więc przyjmuję jakąś wartość domyślną):

Kopiuj
class CarFileRequest(val color: String)

Chcę to sobie wrzucić do domeny jako CarRequest, żeby potem coś tam z tym działać. Czy w takim razie mówisz, ze powinienem zrobić dwa osobne serwisy zamieniające mi te obiekciki? Co jest nie tak w dodaniu do nich funkcji toCarRequest()?

Jestem początkujący, więc nie wykluczam, że błąd jest w ogóle dużo wyżej w moim projekcie/zrozumieniu, jestem otwarty na sugestie :)

EDIT: Widzę, że dorzuciłeś coś jeszcze. Spoko, widzę sens w rozdzieleniu tego jeśli np. chcemy używać tych obiektów w dwóch miejscach. Ale tutaj ewidentnie klient służy do jednej rzeczy, a pewnie w przyszłości się to nie zmieni. Chciałbym utrzymać architekturę jak najprostszą

edytowany 2x, ostatnio: mythflame
KamilAdam
  • Rejestracja:ponad 6 lat
  • Ostatnio:29 dni
  • Lokalizacja:Silesia/Marki
  • Postów:5505
1
Shalom napisał(a):

Wtedy mamy zależność domeny od infrastruktury, co raczej nie jest dobrym patternem

? Masz tylko zależność od DTO bo przecież konkwertujesz sobie to na jakieś DTO. Nie widzę tu żadnej infrastruktury.

Może jestem w błędzie, ale byłem pewien że infrastruktura to właśnie między innymi DTO i klienty.
(W najprostszym podziale przecież mamy tylko domenę i infrastrukturę. Więc jak coś nie jest domeną to musi być infrastrukturą).
Nie mówię że lekki klient jest bez sensu. Jest sensowny zwłaszcza jak wydzielamy go jako osobną bibliotekę i wtedy wszystkie mikroserwisy korzystające z serwisu A mogą korzystać z tego klienta. A nie że wszędzie muszą rzeźbić od początku własnego klienta. W zasadzie pomysł OPa sprowadza nas do rzeźby własnych klientów :(

Dodanie tam zależności do domeny to jakiś hardkor. Ktoś kto chce używać serwisu potrzebuje znać endpointy + jak zmapować odpowiedź na jakieś DTO. W efekcie client nie powinien zawierać nic więcej zeby był lekki.

Dlaczego dodanie w infrastrukturze zależności do domeny to hardkor? Przecież w drugą stronę zależność jest zakazana a jakaś musi istnieć?


Mama called me disappointment, Papa called me fat
Każdego eksperta można zastąpić backendowcem który ma się douczyć po godzinach. Tak zostałem ekspertem AI, Neo4j i Nest.js . Przez mianowanie
edytowany 5x, ostatnio: KamilAdam
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
1

@KamilAdam pisałem o sytuacji kiedy masz serwis i chcesz udostępnić do niego programowego klienta, tak zeby inny serwis mógł zrobić:

Kopiuj
MyClient client = new MyClient(host, port);
SomeDtoResponse response = client.invokeSomeAction(someDtoParameter);

I jednocześnie żeby nie trzeba było do tego wciagnąć całej domeny tego docelowego serwisu ;) Bo przecież ona cię w ogóle nie obchodzi. Obchodzi cię możliwość wykonania operacji + DTO.
Jak widać DTO są tu odrębnym elementem a nie częścia domeny ani infrastruktury, one co najwyżej mają zależność na te klasy.

Jednocześnie nie widzę nic zakazanego w tym żeby domain miało zależność do tych gołych DTO jeśli ktoś bardzo by chciał ją mieć.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 2x, ostatnio: Shalom

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.