Wpis z mikrobloga

Problem: Mam dwie encje A i B jako klasy mapowane przez ORM Hibernate. Struktura wygląda tak, że jedna encja jest w katalogu wewnętrznym drugiej packageA.packageB. Chciałem hermetyzować obie encje do modifiera package-private. Jest w ogóle możliwe, aby zachować relację pomiędzy tymi klasami? Istnieją jakieś patterny na tworzenie relacji pomiędzy prywatnymi encjami w różnych katalogach?

Czytając dokumentację hibernate nie ma tam ograniczeń dotyczących modyfikatora zasięgu klasy, ale równocześnie wszelkie przykłady, także w internetach, operują na publicznych klasach, co znacznie upraszcza problem tworzenia relacji.

Pytanie jest też takie czy może to ja nie pojmuję zbyt dosadnie enkapsulacji i usuwania wszędzie modyfikatora public? Chowanie przed światem klas z adnotacją entity jest pożądanym działaniem, czy tylko utrudnianiem sobie życia i ograniczeniem w mapowaniu relacji pomiędzy klasami?

Myślałem jeszcze nad usunięciem mapowania relacji i utworzeniem jakiegoś wrappera ze scope na prototype do pozbierania pojedynczych encji, lecz wiąże się to z insertowaniem danych przez native Query, co dość mocno uzależnia kod od infrastruktury. Dodam też, że tabele tworzę w Liquibase niezależnie od Hibernate, więc nie wpływa on na kształt encji w bazie danych.

#java #spring #naukaprogramowania #programowanie #programista15k
  • 13
@DoubleAxxis: ma to sens, bo przypuszczam, że mieszam dwa paradygmaty dotyczące encji. Co prawda tworząc klasyczne POJO nie ma tam zbyt wiele do ukrycia, jednak w przypadku przechowywania logiki biznesowej w danych encjach wypadałoby już to schować przed światem. No nic, dzięki, chociaż nie będę musiał drążyć dokumentacji przy tak trywialnym problemie, a wątpliwości dotyczące architektury odłożę na przyszłość. ( ͡° ͜ʖ ͡°)
@mojemirabelki:

Chciałem hermetyzować obie encje do modifiera package-private. Jest w ogóle możliwe, aby zachować relację pomiędzy tymi klasami?

Nie robić package-private ( ͡° ͜ʖ ͡°)

Chowanie przed światem klas z adnotacją entity jest pożądanym działaniem, czy tylko utrudnianiem sobie życia i ograniczeniem w mapowaniu relacji pomiędzy klasami?

W większości przypadków utrudnianie sobie życia. Dodaj sobie do tego całego pomysłu testy jednostkowe.
inb4 refleksja
@Edelner: myślałem nad tym, ale robi się wtedy straszny syf w domenie, bo każda encja ma swoje dao, serwisy, interfejsy, wyjątki. Np User ma relację z Role, a Role ma kolejne zależności, więc pakiet rozrasta się do co najmniej kilkunastu klas. Wtedy wszystkie encje w relacji należałoby trzymać w katalogu roota, a to wydaje się bez sensu. Generalnie w tym miejscu trafiam na wybór pomiędzy enkapsulacją, a mapowaniem relacji w Hibernate
@retardo: to prawda, choć miałem na myśli wyłącznie encje, bo całą logikę dalej mogę schować w prywatnych serwisach za interfejsami lub fasadą. Muszę sobie przeczytać jakąś książkę o DDD, bo tam część logiki trzyma się w encjach, a nie bardzo wiem jak wygląda wtedy interakcja z repo.
@bootcamp_java_developer: trochę śmieszna zasada w kwestii architektury systemu, bo istotą nie jest prostota posiadanych interfejsów, a przewaga elastyczności nad enkapsulacją. Równie dobrze mógłbym to porozbijać na mniejsze paczki, wywalić mapowanie ORM i stworzyć interfejsy z native query, ale straciłbym niezależność kodu od infrastruktury, a jeśli chciałbym w przyszłości podmienić bazę danych to do wywalenia miałbym interfejsy dao, bo nie korzystałbym z hibernate ani jpql. Czytając ten super simple kod w internetach
chorobliwe hermetyzować


@mojemirabelki: A może nawet paranoicznie, bo trochę tak to wygląda ( ͡° ͜ʖ ͡°). Nie ukryjesz encji przed światem, uparty dev i tak dostanie się tam refleksją a jak się wkurzy to zapuka sobie sam przez JDBC i dopiero będzie #smieszekpozakontrolo (literalnie).

Teoretycznie dałoby radę ukryć encje zamykając je jako package-private w pakiecie, w którym będzie logika domenowa ale to dopiero się zrobi syf, bo
@PaaD: racja. choć segregowanie interfejsów dalej mam zachowane, bardziej chciałem zwrócić uwagę na przeniesienie istoty problemu, choć się niefortunnie wyraziłem. Z tym invoke celna uwaga.

Generalnie dochodzę do wniosku, żeby pogodzić ze sobą dwa podejścia i zostawić publiczne klasy, choć z prywatnymi konstruktorami i skorzystać z wrappera do ich obsługi, co by nie przyszło nikomu postronnemu (albo mi w przyszłości) tworzenie obiektów zależnych od siebie pojedynczo. ( ͡° ͜ʖ