Wpis z mikrobloga

Czy jest sens mieć dwa oddzielne modele dla encji biznesowych i encji np. JPA czy documentów Mongo? Czasami można usłyszeć, że tak, ale widzę w tym podejściu pewne problemy.
1.Dla każdej encji biznesowej musimy robić adekwatną encję bazodanową, mappera i repozytorium/dao co zwiększa ilość kodu i czas dowożenia projektu. Np. dla 5 encji jest to 10 dodatkowych klas (5 dla encji i 5 mapperów) a już dla 10 encji jest to 20 dodatkowych klas. Jak widać ilość tego dodatkowego kodu rośnie dość szybko.
2.Zmiana na innych sposób zapisu danych (np. z JPA na Mongo) jest czasochłonna co wynika z punktu 1. Jeśli nie mielibyśmy tego rozdzielenia na encje biznesowe i encje bazodanowe, to wystarczyłoby tylko pozmieniać dosłownie parę adnotacji (tak, tak wiem adnotacje nie są zbyt fajne, ale alternatyw jakoś nie widać za bardzo) i napisać repozytoria/dao. Załóżmy, że mamy te 10 encji czyli modyfikacja tych 10 encji + repo/dao vs 20 dodatkowych klas + repo/dao. Wybór wydaje się prosty.
3.Myślę, że do większości projektów wprowadzą to niepotrzebną złożoność i komplikacje, co utrudnia wejście do takiego projektu nowym osobą i utrzymywanie go.
Jestem przede wszystkim ciekaw z jakim podejściem spotykacie się w pracy. Zapraszam do dyskusji.
#java #programowanie #naukaprogramowania #programista15k
  • 15
Np. dla 5 encji jest to 10 dodatkowych klas (5 dla encji i 5 mapperów) a już dla 10 encji jest to 20 dodatkowych klas.


Z ciekawości spytam co to za gówniany ORM że wymaga takich rzeczy? Zasadniczo wszystkie te rzeczy się powinny automatycznie generować z klasy.

Oczywiście mając ogarnięty dobry micro ORM, mogę sobie zrobić tyle struktur ile potrzebuje mapowanych nawet na te samą tabele, bo niby czemu nie?
3.Myślę, że do większości projektów wprowadzą to niepotrzebną złożoność i komplikacje, co utrudnia wejście do takiego projektu nowym osobą i utrzymywanie go.


@Edelner: tylko jeśli masz miszmasz w kodzie. Jak masz clean/onion architecture i dobrze jest wszystko porozdzielane to ci się nie miesza wszystko bez sensu
@Edelner: Pchanie jednej encji bazodanowej jest pozorną korzyścią. Jakakolwiek zmiana w bazie powoduje problemy, a tutaj wystarczy zmienić tylko mapper. Zresztą, pchanie wielkiej encji bazodanowej w jednej transakcji po całym kodzie, to proszenie się o kłopoty, patrząc na sposób w jaki JPA zarządza encjami
Z ciekawości spytam co to za gówniany ORM że wymaga takich rzeczy? Zasadniczo wszystkie te rzeczy się powinny automatycznie generować z klasy.


@Krolik: no ale wtedy gdzie chcesz umieścić nietrywialną logikę? Potrzeba klasy do reprezentowania wyniku zapytania i klasy (lub funkcji, jeśli nie piszemy w Javie/C#) na zmapowanie tej klasy na obiekt domenowy. Jeśli generowałoby się to automatycznie to w sumie można używać wszędzie jednego modelu o czym w sumie jest
@Edelner: ciężko powiedzieć. Jak wiesz, że jest potencjał na jakąkolwiek logikę to robisz grzecznie ładne mapowania, bo inaczej się nie da. Kiedyś próbowałem zrobić takie podejście w stylu jeden model na wszystko tj. te same protobufy używane w API, logice i bazie. Kluczem było testowanie wszystkiego na poziomie API, co pozwalało na bezbolesny refaktor. I jeśli gdzieś dochodziła potrzeba posiadania logiki to refaktorowałem wszystko żeby było tak jak pan jezus powiedział.
no ale wtedy gdzie chcesz umieścić nietrywialną logikę?


@Saly: Logikę się umieszcza jako osobny kod, a nie w strukturach danych. Struktura to tylko struktura - przechowuje informacje i ewentualie sposób mapowania jej na strukturę w bazie, aby orm potrafił ją odczytać / zapisać i tyle. Po cholerę pchać do takich struktur logikę?

Generalnie jak masz wątpliwości to wybierz to co jest prostsze w tej chwili. A dogmatystami DDD czy OOP nie
@Edelner: wyobraź sobie, iż udostępniasz swój serwis dwóm klientom, którzy płacą gruby $ za to.
Jeden chce zmianę, a drugi za chiny ludowe nie wdroży żadnej nowej zmiany. Z twoim podejściem rozwiąż ten problem zakładając, że masz jedną działającą instancję (i nie dokładasz innych)
Logikę się umieszcza jako osobny kod, a nie w strukturach danych. Struktura to tylko struktura - przechowuje informacje i ewentualie sposób mapowania jej na strukturę w bazie, aby orm potrafił ją odczytać / zapisać i tyle. Po cholerę pchać do takich struktur logikę?


@Krolik: OP napisał, że są dwie klasy: encja i mapper. Pierwszą rozumiem jako głupią klasę bez dodatkowej logiki (ewentualnie jakieś podstawowe rzeczy typu adnotacje/automatyczne mapowania na podstawie typów)
@Krolik: Nie, nie zrozumiałeś chyba. Te dodatkowe klasy trzeba tworzyć jak chcesz rozdzielić encję orm od encji biznesowej. Jak masz jeden typ encji to orm normalnie sobie automatyczni to mapuje na tabelki.

@WyjmijKija: Ja nic nie napisałem o bałaganie czy mieszaniu tylko o dodatkowej pracy i ilości kodu.

@Sztuczny_Snieg: Jeśli zmienia się np. schemat bazy danych to w tym podejściu z oddzielnymi encjami, to muszę nanieść zmiany w encji
Nie powinno się oddzielać danych od logiki, bo to po pierwsze prowadzi do możliwości wprowadzania obiektu w niepożądany i absurdalny stan np. User z pustym namem i ujemnym agem


@Edelner: Nie o takiej logice pisałem. Oczywiście masz rację, że obiekt powinien być napisany tak aby nie dało się go wprowadzić w nieprawidłowy stan. Czyli walidacja argumentów w konstruktorze i najlepiej wszystkie pola final aby nie dało się obiektu zepsuć. Jak trzeba