Non-anemic entities

Non-anemic entities
Bambo
  • Rejestracja:ponad 10 lat
  • Ostatnio:8 miesięcy
  • Postów:779
0

Cześć, ostatnio gdzieś tu na forum znalazłem sprzeczną z moim ostatniem podejściem, które stosujemy w pracy problematyką. Chodzi o NIEANEMICZNE encje. W pracy spotkałem się po raz pierwszy z tym i architekci wprowadzili taką zasadę u nas- podobno źródłem tego jest książka o DDD - aby encje hibernatowe posiadały również metody biznesowe.

Tutaj jednak czytałem, że to jest złe. Mi się z tym dobrze pracuje.
Ktoś mógłby ruszyć bardziej ten problem ?

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

Mam nadzieje że żartujesz teraz :D A jeśli nie to zalecam szybką ewakuacje w tejże firmy bo macie architektów idiotów.
Encje w rozumieniu DDD nie mają NIC WSPÓLNEGO z klasami @Entity mapującymi tabele w bazie danych. @jarekr000000 się na pewno ucieszy że ktoś tak mocno nie zrozumiał DDD że zaczyna promować jego ulubioną metodykę "encja na twarz i pchasz".
Jesteś pewien że ty czegoś źle nie zrozumiałeś czasami? :)


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
VA
"encja na twarz i pchasz" -> made my day :)
rubaszny_karp
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad 6 lat
  • Postów:152
0

"encja na twarz i pchasz".

title


small data and high latency
hcubyc
  • Rejestracja:ponad 12 lat
  • Ostatnio:prawie 3 lata
2

To fakt, DDD promuje nieanemiczne encje, ale to nic nowego, bo to po prostu programowanie obiektowe. Jeżeli się nie operuje na strukturach danych, a obiektach to te drugie powinny się charakteryzować jakimś zachowaniem. Jeżeli masz struktury danych, które w Javie są klasami jak wszystko inne, ale każda operacja dzieję się tylko za pomocą klas 'serwisów', które robią głównie getX, setY to cięzko mówić o obiektowości. Encje w DDD tak jak napisał Shalom nie mają nic wspólnego z encjami w ORMach i jeżeli trzymać się sztywno założeń DDD to są złamaniem reguł, bo wiążesz kod biznesowy z warstwą infrastruktury, ale widziałem różne podejścia i generalnie może mieć to sens, by encje hibernatowe również posiadały jakieś zachowanie i były czymś więcej niż struktury danych, z czasem zespół pójdze po rozum do głowy i stwierdzi, że jednak lepiej zrobić to po bożemu


Limitations are limitless > ##### Ola Nordmann napisał(a)
> Moim językiem ojczystym jest C++ i proszę uszanować to, że piszę po polsku.
Bambo
  • Rejestracja:ponad 10 lat
  • Ostatnio:8 miesięcy
  • Postów:779
0

Ale to chyba nie jest pchanie encji na twarz ? Przecież do kontrolerów zwracam już skonwertowane dtosy. Tutaj np encję hibernatową: Event, która ma np. taką metodę biznesową jak finish(), która tam sprawdza jakieś warunki i coś robi np. z polem date. Potem w serwisie robię eventsRepository.save(event);

Co w tym jest złego i jak to inaczej robić ?

hcubyc
  • Rejestracja:ponad 12 lat
  • Ostatnio:prawie 3 lata
0

Pół biedy - tak bym to określił, bo z tego co rozumiem to jedynym narzutem kody infrastrukturalnego na encję są adnotacje hibernatowe. Nie jest to takie złe, ale w idealnym świecie miałbys encję w rozumieniu DDD bez adnotacji i implementacja repozytorium zawierałaby klasę, która dopiero byłaby wykorzystywana przez ORM czy tam cokolwiek innego. Generalnei często zdarza się (prędzej lub później zawsze?), że jeżeli klasa zaadnotowana jako Entity czy z czego tam kto korzysta przecieka i jest pisana pod katem tego, żeby być mapowalną na tabele, a to już jest szczegół, który nie jest wymagany do poprawnego działania biznesu/domeny. Dlatego idealnym rozwiązaniem jest całkowite rozdzielenie kodu biznesowego od wszystkich zależności


Limitations are limitless > ##### Ola Nordmann napisał(a)
> Moim językiem ojczystym jest C++ i proszę uszanować to, że piszę po polsku.
edytowany 2x, ostatnio: hcubyc
Shalom
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
1

@Bambo: widze że oglądałeś tylko pół talka na temat "encja na twarz" ;) Wystartuj teraz tutaj https://youtu.be/SxqK8jo7vdY?t=1795
Generalnie to jest zły pomysł zeby sobie tak mocno związać model danych z logiką biznesową, bo zwyczajnie ograniczasz sobie możliwości zmiany czegokolwiek i dodatkowo na 99% zacznie to wyciekać. Ty sobie niby zrobisz jakieś metody biznesowe, ale obok nich będzie "get" i "set" i problem gotowy.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 2x, ostatnio: Shalom
WeiXiao
  • Rejestracja:około 9 lat
  • Ostatnio:około 2 godziny
  • Postów:5139
0

explain like im 5 not even junior

dlaczego get = zło?

edytowany 5x, ostatnio: WeiXiao
Shalom
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

Sam w sobie get to nie zło, jeśli siedzi w jakimś DTO/strukturze danych - siłą rzeczy musi tam coś takiego być.
Ale get w obiekcie domenowym zwykle oznacza że łamiesz enkapsulacje, bo zamiast udostępniać jakieś "funkcjonalności" to ty po prostu po chamsku wystawiasz przez publiczne API stan twojego obiektu. Potem próba zmiany wewnętrznej struktury takiego obiektu jest praktycznie niemożliwa bez zmiany w połowie codebase.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 4 godziny
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4708
1

Jak już miałbym wybierać między dwoma zrypanymi architekturami to chyba bardziej mnie wkurza wersja z torebką na głowie. Każde entity hibernatowe ma 1 do 1 odpowiednik w DTO. Udajemy, że jest jakaś separacja. Z drugiej strony dzięki powszechnemu niezrozumieniu działania JPA/Hibernate architektura taka gwarantuje dobrą zabawę: zmiany, które się zapisują do bazy oraz zapisy oraz nulle w bazie, które nie wiadomo z czego się biorą. Najlepsi potrafią nawet generatory kodu do tego mapowania DTO <-> hibernate napisać. Miodzio.

Wersja bez DTO, wydzielonej logiki , gdzie wszystko jest w encjach to przynajmniej jasne postawienie sprawy. Bez udawania. Takie architektoniczne: biore 150 za godzinę, nie musisz mi kupować drinka.

A co do: architekci w mojej firme przeczytali książke, pojechali na konrefencję.... to można by ładny poemat napisać. Jak ktoś całą głowę ma prostokątną, bo 5 lat tłukł CRUDy do tabelek, to łatwo z tego nie wyjdzie.
Zresztą. Poniżej przesławny skecz - w polskiej wersji językowej.


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 5x, ostatnio: jarekr000000
Zobacz pozostałe 6 komentarzy
Bambo
@jarekr000000: No ok, ale jakoś musisz dane wystawiać na front no nie ? Jakoś front się musi komunikować z backendem ? Czyli sugerujesz, że jeśli dostanie się od klienta do zrobienia aplikacje, która praktycznie nie ma logiki tylko same transakcje z bazą danych to można totalnie zrezygnować z backendu i prosto z frontu dostawać się do DB?
jarekr000000
@Bambo - no jakbym dostał od klienta aplikację, która praktycznie nie ma logiki to bym użył spring boota i zrobił przelotkę do bazy danych. Nie wiem po co się takimi aplikacjami zajmować zresztą. To w końcu strona o programowaniu.
Bambo
@jarekr000000: No ale przecież takich aplikacji jest bardzo dużo obecnie. Może niekoniecznie takich, które tylko wyciągają i wstawiają suche dane do bazy, bo przecież trzeba coś powalidować itd. No ale np pisałem niedawno aplikacje mobilną typu instagram to tam też był wystawiony prosty rest, który zwracał listę postów, zdjęć userów itd - praktycznie żadnej logiki. CRMy również to głównie zwracanie wierszy z bazy danych. Ostatnio co pisałem coś "logicznego" to parsowanie jakiegoś query na liste specyfikacji przy filtrowaniu i sortowaniu danych.
Bambo
Może po prostu tak wyszło, że pracuję przy projektach, które tej logiki mają bardzo mało. No a Ty w swoim przypadku przy takich apkach, gdzie jednak coś się dzieje to przecież koniec końców i tak musisz wrzucić dane na front no nie ? I wtedy dajesz resta tak ?
jarekr000000
@Bambo - RESTa daje czasem - jak pasuje. Czasem WebSockety, czasem SSE, a często po prostu chamskie JSONowe API (które ma tą przewage nad klasycznym RESTEm, że obbługuje trochę więcej "czasowników"). Poza tym w RESTOwych interfejsach też nie robię raczej PUT i DELETE. (https://www.thoughtworks.com/radar/techniques/rest-without-put)
Bambo
  • Rejestracja:ponad 10 lat
  • Ostatnio:8 miesięcy
  • Postów:779
0

To w takim razie koledzy ... macie może gdzieś jakiś przykład albo moglibyście sami podać, w którym jest jakiś prosty kontroler, serwis, encja JPA i encja domenowa ? Bo szczerze mówiąc też mi się nie podoba pchanie logiki do serwisu, która ustawia coś na obiekcie, a szczerze mówiąc nigdy się nie spotkałem z taką architekturą, gdzie te encje domenowe są wydzielone od JPA.

Nie wyobrażam sobie nie mieć getterów w encjach JPA - jak wtedy konwertujemy encje JPA na jakieś dtosy, które chcemy zwrócić ?

Zdr :)

edytowany 1x, ostatnio: Bambo
FI
FI
  • Rejestracja:około 10 lat
  • Ostatnio:około 4 lata
  • Postów:471
0

tez chetnie bym zobaczyl jakies repo gdzie to jest zastosowane :)

Zobacz pozostałe 16 komentarzy
Bambo
A co jeśli edytujemy encje jpa a nie wpychamy nową ?
KA
Nie widze problemu
Bambo
@hcubyc: ale czy w takim przypadku nie mówimy za dużo encji biznesowej ? Skoro potrafi się ona mapować do Encji JPAi z niej tworzyć to przecież łamiemy zasadę, że encja biznesowa wie coś o infrastrukturze no nie ?
hcubyc
Troszkę tak jest, ale nie odkryłem/widziałem lepszego sposobu. Obecne rozwiązanie pomaga mi tworzyć encje biznesowe takie jak potrzebuję i kolejno 'encje JPA' też z uwzględnieniem tego, że to musi się odpowiedni mapować. Plus jest taki, że z mojej encji mogę wymazać kod mapowania i mi to w niczym nie psuje całego biznesu. Minus taki jak zauważyłeś - encja biznesowa tworzy coś na wzór DTOsa. Nie znalazłem innego rozwiązania, chociaż można by zostawić encję biznesową samą sobie i w warstwie infrastruktury ogarnać to np refleksją, ale to już IMHO by bardziej śmierdziało
KA
Ale ten dto tez moze byc bardziej value objektem niz glupim dto. Moze tez byc to np. Immutable klasa.
T6
  • Rejestracja:ponad 10 lat
  • Ostatnio:3 miesiące
  • Postów:22
0

Ja tez.

0

inna sprawa, ze JPA po prostu jest mało into DDD :D

jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 4 godziny
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4708
3
filemonczyk napisał(a):

tez chetnie bym zobaczyl jakies repo gdzie to jest zastosowane :)

Off - top. MSPANC.

Programista korpo-javowy pojechał dla odprężenia na ryby i, jak to zwykle w takich przypadkach bywa, złapał złotą rybkę.

  • Wypuść mnie do wody, a spełnię twoje życzenie! - błagalnie krzyknęła złota rybka.
  • Jak to życzenie? Jedno ?! Normalnie są trzy! - dopytał zaskoczony, ale czujny programista.
  • Bo ja jestem rybka Enterprise Edition i obsługuję tylko jedno życzenie na złowienie - wyjaśniła - poza tym, proszę dawaj życzenie szybko, bo się duszę na powietrzu.
  • Ok.... w takim razie wiesz co.... chcę super potężnego laptopa. Ma mieć moc wszystkich chińskich serwerów, ma ważyć pół kilo, bateria ma trzymać 10 godzin.. no i ma na tym działać arch linux....
  • Stop - przerwała rybka - Troszkę przesada z tym laptopem. Nawet jak Ci takiego zrobię, to Cię złapie FBI i zapyta skąd masz. Będzie chryja.... wymyśl coś innego lepiej.
  • Dobra!... to może weź mi daj taki przykładowy dobrze zrobiony projekt w DDD z użyciem JPA i Springa. Żeby był czysty kod, i dobre testy, i w ogóle...
  • W jakim kolorze ma być ten lapek? - przerwała ponownie rybka.

jeden i pół terabajta powinno wystarczyć każdemu
edytowany 7x, ostatnio: jarekr000000
rubaszny_karp
tu jest potrzebna nauka od podstaw i świadomość #makejavagreatagain #javateam
nie100sowny
  • Rejestracja:około 9 lat
  • Ostatnio:dzień
  • Lokalizacja:Kraków
  • Postów:402
4

DDD dla mnie to przerost buzzwordów nad treścią.
Do sukcesu potrzeba tylko znajomości: Javy, programowania obiektowego, zasad SOLID, wzorców projektowych (nie wszystkich) i znajomości heksagonalnej architektury. Brzmi prosto, ale takie nie jest :P

Jeżeli masz skomplikowany problem biznesowy:

  1. Tworzysz moduł w projekcie, gdzie modelujesz problem za pomocą niemutowalnych klas Javy, strategi, fasad i kompozycji zamiast dziedziczenia. W tym projekcie gdy potrzebujesz zrobić coś technicznego to robisz interfejs (np. *Repository, *Client) i nic więcej. Zależności nie ma - chyba, że jakieś utile jak Vavr, Lombock, Slf4j lub wyjątkowo cięższe jak Apache POI.
  2. Tworzysz drugi moduł, gdzie importujesz pierwszy moduł i implementujesz wszystkie interfejsy. Dodatkowo kleisz to w jeden system ręcznie lub za pomocą Spring DI / Guice.
  3. Odkrywasz, że JPA sprawia same problemy i niemal nie da się go użyć. :D Stosujesz JDBC lub JOOQ do implementowania Repozytoriów.
    Porada: jeżeli już jesteśmy zmuszeni użyć jakiegoś Spring Controllera, który potrzebuje mutowalny obiekt, możemy mu dać builder od Lombocka.

Jeżeli masz problem typu CRUD:

  1. Robisz jeden moduł ze Spring Data i Encjami. Gotowe.

SQL to świetny język dla skomplikowanych przypadków. I wolę analizować 10 zapytań biznesowych SQL niż 5 encji hibernate.
Nie wiem czemu ludzie lubią takie magie jak Spring i Hibernate w 2018 roku. Te frameworki włażą butami w wasze klasy, modyfikują stan, rzucają wyjątki itp. Same problemy.


"Gdy się nie wie, co się robi, to się dzieją takie rzeczy, że się nie wie, co się dzieje"
edytowany 4x, ostatnio: nie100sowny
Zobacz pozostały 1 komentarz
FI
filemonczyk
dla kolejnych ludz wrzuce tez tu, ten sam talk w lepszej jakosci https://www.youtube.com/watch?v=ILBX9fa9aJo
KA
A widziales moze podobna prezentacje ale po angielsku?
FI
filemonczyk
nope
KA
smuteczek :( bo chętnie bym tez niektorym zagraniczniakom pokazal
hcubyc
  • Rejestracja:ponad 12 lat
  • Ostatnio:prawie 3 lata
0

@nie100sowny:
Zgodzę się z tym ;) dodatkowo wprowadza kilka rzeczy, które też często są oczywiste jak ubiquitous language. IMHO warto się z tym zapoznać


Limitations are limitless > ##### Ola Nordmann napisał(a)
> Moim językiem ojczystym jest C++ i proszę uszanować to, że piszę po polsku.
nie100sowny
Jasne, że warto ale jak to z takimi księgami bywa ludzie zwykle czytają i nie rozumieją. :)
Bambo
  • Rejestracja:ponad 10 lat
  • Ostatnio:8 miesięcy
  • Postów:779
0

@nie100sowny:

Masz przykład dobrze zaprojektowanego takiego modułu ze skomplikowanym problemem ?
Nadal nie mogę znaleźć tego miejsca, w którym JPA tworzy problem. Albo inaczej .. sam się kiedyś zastanawiałem, że w tym JPA/Hibernata to w sumie bardzo dużo adnotacji i magii i trzeba tego używać, aby było optymalniej, a przecież walnąć jakieś natywne SQLe w JDBC to przecież nie jest problem a mamy tak dużo wtedy kontroli nad tym wszystkim. Chyba, że jest jeszcze inny powód dla którego skutecznie się na tym forum beszta to JPA ?

A co do typowego CRUDA, napisałeś, że spring data i encje, ale co ? Przecież jakaś tam logika w serwisach jest - nie masz żadnych dto ?

Cały czas staram się dociec jak wygląda flow od kontrolera do konkretnej zmiany w tabelce bazy danych i odwrotnie. No bo wychodzi na to, że:

  1. Jak jest encja jpa nieanemiczna i zamiast setterów udostępnia konkretne biznesowe metody + ma gettery aby zbudować jakieś dto'sy do wypychania na zewnątrz to źle
  2. Jak encja jpa jest czystą strukturą i jej logika znajduje się w serwisie to też źle.

Jak żyć :D Ale dzięki za odpowiedzi :D

nie100sowny
Dokładnie do tego między innymi nawiązuje :P
FI
filemonczyk
https://www.youtube.com/watch?v=ILBX9fa9aJo to samo ale lepiej nagrane
0

czy wg Martina Fowlera (https://www.martinfowler.com/bliki/AnemicDomainModel.html) **nie **pisanie funkcji biznesowych w klasach z adnotacją @Entity - jest anty-wzorcem? bo chyba zle to rozumiem

hcubyc
dobrze rozumiesz, edit: źle zrozumiałem pytanie, shalom wytłumaczył wszystko 2 komentarze niżej
KA
JPA bywa tak okrutne... ze z drugiej strony strach sie bac umieszczac tam logike :D
Shalom
A czy Folwer gdziekolwiek tam mówi cokolwiek o JPA, Hibernate czy @Entity? On mówi generalnie o tym że nie lubi podejścia stosowanego czesto w SoA, że masz serwisy które łykają jakieś DTO i wypluwają DTO/struktury danych.
Bambo
@Shalom: a jakaś konkretna różnica między strukturą danych a DTO jest ?
Shalom
Nie. Co najwyżej kwestia przeznaczenia - dto to struktura do przekazywania danych między serwisami.
SZ
  • Rejestracja:około 11 lat
  • Ostatnio:ponad 4 lata
  • Postów:616
1

U nas doszliśmy do wniosku, że lepszy dobry transaction script niż słabe DDD.
DDD jest trudne zwłaszcza kiedy projekt tworzymy od początku, gdzie ciężko jest wyznaczyć Aggregate Root'y (BoundedContext), z drugiej strony kogo stać aby 5 letni projekt wykonany w transaction script przepisać na DDD. (no chyba Allegro, Amazona i Netflix'a)...później się tych chwalą i my też tak chcemy :-p

Aby zrobić DDD trzeba mieć mocny zespół(albo robić dużo code-review, spotkań projektowych) jednak na rynku jest przewaga średniaków, dla których zrozumienie controller->service->repo->entity jest prostsze/możliwe.....

Co do przykładu to można zobaczyć prekursora DDD w Polsce w akcji na https://github.com/BottegaIT/ddd-leaven-v2

KA
mi ogolnie DDD wydaje sie mocno verbose.
Bambo
  • Rejestracja:ponad 10 lat
  • Ostatnio:8 miesięcy
  • Postów:779
0

@nie100sowny:
A w przypadku prostego projektu, gdzie nie ma dużo logiki to jak robisz ?
Bo ja się cały czas zastanawiam, czy to całe DDD z tymi CQRSami nie powinno być stosowane do wielkich projektów, a jeśli ja mam 5-6 modułów i raczej średnie wielkości aplikacje to czy to w ogóle jest sens tego używać.

I jeszcze jedno mnie zastanawia. Które klasy u nas powinny być immutable ? Tylko Value Object Class, które są opakowaniem np adresów email, zip codów, nr tel itp. ?

Własnie na dniach będę zaczynał pisać raczej małej wielkości resta do aplikacji mobilnej. Chciałbym w niej zastosować jakąś lepszą technologię. Do tej pory moja kariera springowa przebiegała tak:

  1. Encja na twarz bez żadnych dtosów
  2. Oddzielenie encji jpa od dto, ale cała logika była w serwisach, więc był to raczej kod proceduralny
  3. Encje jpa z logiką biznesową, odchudzone serwisy, dtosy z konwerterami.
  4. ?
edytowany 3x, ostatnio: Bambo
Koziołek
Moderator
  • Rejestracja:około 18 lat
  • Ostatnio:22 dni
  • Lokalizacja:Stacktrace
  • Postów:6821
1

A ja mam jeszcze inne doświadczenie z podejściem DDD i używaniem w nim JPA. Stary dobry CQS. Polecenia, czyli C przyjmują jako parametry wejściowe encje JPA, albo ich fragmenty. Dzięki temu operacje CUD są stosunkowo proste i nie trzeba się bujać z dziwnymi translacjami. Zapytania, czyli Q, reprezentują obiekty domenowe zatem z JPA wychodzi projekcja, która po lekkim "ospringowaniu", może być używana dalej w serwisach. Zero magii.


Sięgam tam, gdzie wzrok nie sięga… a tam NullPointerException
SP
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 2 lata
  • Postów:127
0
Bambo napisał(a):
  1. Oddzielenie encji jpa od dto, ale cała logika była w serwisach, więc był to raczej kod proceduralny

To trochę zależy jak popatrzymy na programowanie obiektowe, jeżeli jak na zasoby posiadające stan ze zbiorem funkcji stanowiących ich interfejs, to takie anemiczne encje z interfejsem w postaci serwisów też można traktować jako OOP :p Zbiór końcówek http w sumie też. Zasobem może być encja, ale może to też być rekord w bazie danych albo plik w systemie plików a jego interfejsem zbiór exeków. Trzeba się zdystansować :)
Wrzucanie logiki do encji raczej nie wyjdzie, bo jak jedna encja będzie chciała wywołać metodę drugiej to i tak powinna to zrobić poprzez serwis.
Pisanie DTO to dla mnie strata czasu, odłączona encja też jest DTO tylko trzeba pilnować granic transakcji. Już samo pisanie encji mnie denerwuje i czasem zastanawiam się czy nie byłoby lepiej przerzucić logikę do proc. składowanych :p

jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 4 godziny
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4708
3
student pro napisał(a):

Pisanie DTO to dla mnie strata czasu, odłączona encja też jest DTO tylko trzeba pilnować granic transakcji[...]

Jesli jakiś framework, język, paradygmat wymaga abyś czegoś pilnował, był uważny to to jest właśnie recepta na katastrofę.
Człowiek może być uważny raz na jakiś czas - ale zespół napierniczający kod 5 dni w tygodniu po osiem godzin - nie będzie stale czujny.

Błedy związane z podpiętymi (lub nie ) do sesji encjami JPA są całkiem przykre w debugowaniu.

Mam już całkiem pokaźny zbiór historyjek związanych z tym problemem. Ktoś coś tam zmienił na użytek GUI, debugu...w podłączonej encji i pół bazy się skasowało...
albo podpiął w relacji parent - child obiekt pochodzący z zagnieżdzonej transakcji. Miodzio. Takie rzeczy potrafią całkiem zatrzymać development w projekcie na tydzień lub dwa.

Dla mnie ten aspekt JPA łamie po prostu zasady enkapsulacji.
DTOsy , jakkolwiek w większości projektów zrobione w sposób chory, przynajmniej trochę przed tym zabezpieczają. W JPA ````select new DTO() ``` to w zasadzie podstawa zdrowego trybu życia.


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 2x, ostatnio: jarekr000000
rubaszny_karp
"Błedy związane z podpiętymi (lub nie ) do sesji encjami JPA" - no bez jajec XD używasz młota to miej świadomość że możesz nim sobie zrobić kuku - dodatkowo, nadal nie czyni to młotka słabym narzędziem.
jarekr000000
@rubaszny_karp: To że młotek jest przydatny - nadal to nie czyni go idealnym narzedziem do mycia okien. Mimo, że tysiące próbują, a niektórym - ostrożnym nawet się udaje (nie mają wyjścia - bo mają tylko młotek).
Koziołek
@rubaszny_karp: wiesz, że z pewnego powodu mamy obecnie sandboxing aplikacji, ochronę pamięci, wirtualizację przestrzeni adresowych. Mamy to własnie po to by nie zrobić sobie kuku.
SP
wychodzi na to że hibernate to wirus :D a DTO to wzorzec projektowy który przed nim zabezpiecza
hcubyc
  • Rejestracja:ponad 12 lat
  • Ostatnio:prawie 3 lata
0
student pro napisał(a):
Bambo napisał(a):
  1. Oddzielenie encji jpa od dto, ale cała logika była w serwisach, więc był to raczej kod proceduralny

To trochę zależy jak popatrzymy na programowanie obiektowe, jeżeli jak na zasoby posiadające stan ze zbiorem funkcji stanowiących ich interfejs, to takie anemiczne encje z interfejsem w postaci serwisów też można traktować jako OOP :p

Jak dla mnie to kod strukturalny, definiujesz struktury, a później na nich operację, przez co np. to operujący na strukturze musi ją walidować albo sprawdzać reguły biznesowe.


Limitations are limitless > ##### Ola Nordmann napisał(a)
> Moim językiem ojczystym jest C++ i proszę uszanować to, że piszę po polsku.
Bambo
  • Rejestracja:ponad 10 lat
  • Ostatnio:8 miesięcy
  • Postów:779
0

https://github.com/jakubnabrdalik/hentai <-

Ale tutaj w ogóle nie ma typowych encji biznesowych. Mamy dtosy i konwerter dto -> encja jpa, na które ktoś wcześniej w tym temacie nakrzyczał, że są złe. A logika jest w serwisie (fasadzie).

hcubyc
To bardzo prosty przykład i w tej fasadzie nie ma logiki, poza walidacją tego co wchodzi do modułu i wywołania repozytorium czy utworzenia encji
FE
No właśnie logika sprowadza się do walidacji bo przykład jest prosty - gdyby to było bardziej skomplikowane to byłaby tam jakaś realna logika i pewnie byłyby też inne Fasady np. wstrzyknięte żeby synchronizować funcjonalność.
Bambo
  • Rejestracja:ponad 10 lat
  • Ostatnio:8 miesięcy
  • Postów:779
0

Ok, po tym filmie Jakuba trochę lepiej to widzę i się z tym lepiej czuję. Ale jeszcze rzecz mnie naszła. Jak mamy encje JPA i załóżmy jest to jakaś encja Usera. To czy jeśli user ma jakiś adres, na który składa się miasto, osiedle, kod pocztowy itd, to czy warto ten adres też opakować w jakąś embeddabled encje czy skoro to jest i tak głupia struktura bez żadnych metod to zrobić tam po prostu stringi i inne prymitywy ? Bo wiadomo, obiekty domenowe to będzie user, adres, zipcode, city itd.

hcubyc
  • Rejestracja:ponad 12 lat
  • Ostatnio:prawie 3 lata
0

Tym czego szukasz jest w DDD Value Object, a w świecie poza DDD po prostu strukturą danych. Kilka prymitów, które połączone mają jakiś sens warto zebrać w strukturę/klasę. Łatwiej będzie refaktorować, z czasem może dojdzie jakieś zachowanie etc.

Dawno nic nie robiłem w JPA, ale z tego co rozumiem to obiekt domenowy jak najbardziej powinien zawierać obiekt zagnieżdzony np. adres (zamiast pól adresu jako prymitywy). To jak to zmapujesz to w bazie danych to jest naprawdę szczegół i powinno w dużej mierze zależeć od możliwosći bazy/ORMa. https://en.wikibooks.org/wiki/Java_Persistence/Embeddables - pierwszy przykład wydaje się spoko, nie ma tam żadnego IDka, po prostu umożliwia wbudowanie struktur w jedną tabelę co by kod javowy miał więcej sensu.


Limitations are limitless > ##### Ola Nordmann napisał(a)
> Moim językiem ojczystym jest C++ i proszę uszanować to, że piszę po polsku.
edytowany 2x, ostatnio: hcubyc
Zobacz pozostały 1 komentarz
hcubyc
Jak najbardziej, ale nie powinien mieć identyfikatora - jedyne co powinno odróżniać jedno VO od drugego to wartości (np. dla VO kolor będą to kolejno wartości R,G,B).
Bambo
ale chyba żadna encja biznesowa nie ma identyfikatora ? W sensie no rozumiem, że id mają encje JPA, ale te biznesowe to się z tym nigdy nie spotkałem
hcubyc
Czemu nie? Najlepiej gdyby to był klucz naturalny, ale nie widzę nic złego w kluczu sztucznym. np faktura ma swój nr/ID po którym ją identyfikujesz przez cały jej cykl życia.
Bambo
W sumie tak, ID faktury w sensie biznesowym również ma sens. A powiedz mi. Jeśli chodzi o encje biznesowe to .. nie każda musi być value object tak ? Bo właśnie staram się jeszcze zrozumieć różnice między tymi dwoma pojęciami. No bo encja biznesowa to konkretny obiekt udostępniający swoje zachowanie i może mieć metody, które zmieniają jego stan tak ? I to jest ok. Value Object jest immutable i również ma metody biznesowe z tą różnicą, że nie zmieniają one stanu tylko zwracają nową instancję obiektu. W takim razie każdy value object jest encją biznesową, ale odwrotnie nie.
hcubyc
Tak, encja może, a raczej zawsze będzie mieć też jakiś stan, który będzie się zmieniał z czasem. VO nie jest encją, bo ona może być stanowa, a VO nie może. Tak samo z tożsamością. VO to po prostu prosty obiekt, który identifykują pewne cechy. Kolor to często powielany przykład, definiują go wartości RGB plus może miec jakieś metody np. isMonochromatic
Shalom
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
1

@Bambo ja generalnie jestem mocno przeciwny używaniem w aplikacji prymitywów i klas standardowych, bo mocno ogranicza nam to flexibility przy pisaniu kodu, szczególnie w miejscach gdzie jest spora szansa że coś będziemy zmieniać. Dodanie nowego pola, jak już mamy jakąśtam strukturę/klasę opakowującą, to jest prosta sprawa, ot dochodzi jedna linijka. A jak gdzieś sobie wpiszesz wartość jako Stringa czy Inta to potem już niewiele można zrobić, bo zmiana powoduje konieczność zmiany API które z tego korzystały. Więc trochę zdrowego rozsądku trzeba mieć.
W tym przypadku to choćby dla czytelności warto wyrzucić sobie te dane do osobnej struktury.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
Bambo
@Shalom: ale chodzi Ci o nieużywanie prymitywów tylko w obiektach domenowych, czy w dtosach, które wyrzucam na zewnątrz również. Jeśli np. mam UserDto, które zwracam w endpoincie i ma on pole email to tam też robisz osobno EmailDto i opakowujesz dopiero w to stringa ? Raczej naciągane. W encjach biznesowych rozumiem jak najbardziej.
Shalom
Nie no nie dajmy się zwariować, w przypadku emaila to może nie ma sensu, tak samo jeśli opakowujesz dane i zaraz je gdzieś wysyłasz/konwertujesz na jakiegoś jsona. Ma to sens jesli przetwarzasz te obiekty/dto gdzieś w systemie i je przekazujesz jako argumenty i wartości zwracane. Wyobraź sobie że ten email przesyłasz sobie wszędzie jako stringa, a nagle pojawia się potrzeba zeby razem z emailem trzymać jeszcze jakis alias. Refaktor na pół systemu... O kwiatkach w stylu Map<String,Map<Integer,Map<String,Integer>>> to nawet nie mówie :)
Bambo
  • Rejestracja:ponad 10 lat
  • Ostatnio:8 miesięcy
  • Postów:779
0

@Shalom:
@hcubyc
No ok czyli wychodzi na to, że będę miał lustrzane odbicie. Po stronie biznesu mam takie encje jak User, Adress, ZipCode, Email itd. - z metodami biznesowymi do nich, a po stronie bazy danych mam odpowiadające im struktury danych - encje JPA.

edytowany 1x, ostatnio: Bambo

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.