Mapowanie w DTO vs dedykowany mapper

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ę:

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ć?

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ą.

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

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)

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:

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ą):

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ą

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ć?

1

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

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ć.

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