Hej
W tutorialu, z które aktualnie się uczę jest stosowany Lombok, pozwala on zlikwidować część powtarzalnego kodu.
Spotkałem się z wieloma opiniami, że jednak lepiej z niego nie korzystać. Chciałbym poznać Wasze doświadczenia z tym projektem i opinie nt. tego, czy powinno się tym w ogóle interesować w 2022 roku.
Wszystko jest dla ludzi.
Lombok skomplikowany nie jest a i tak często ludzie nie potrafią z niego korzystać (przepisują na pałę adnotacje które się np. pokrywają).
Ja w projekcie lomboka mam, działa, jeszcze nie sprawiał problemów.
To nie Lombok jest zły. To Java jest zła, bo rozwlekła. Lombok próbuje zrobić z Javy zwięzły język, ale dalej wygląda to jak potwórek, czyli więcej adnotacji niż kodu. A można wziąć Kotlina lub Scalę i mieć w standardzie języka to co daje Lombok i dużo więcej
"Naprawia" te cechy Javy, które są zużyte przez czas. Projektując w pierwszej połowie lat 199x tak się to widziało, ale czas leci do przodu - a świat javowski założył 100% kompatybilności ze starymi wersjami.
Jak jako student/absolwent sprzedawałem swojego fiata 126p, wielką zaletą dla nabywcy był cały bagażnik części zapasowych, pompek, rurek, drutów itd To był taki lombook
Właściwie to samo daje dobre IDE - choć w inny sposób, dłuższy, choć nie klepany palcem, kod siedzi w sursach: generowanie konstruktorów, toString'a itd Kod dłuższy, ale np da się postawić breakpoint. Osobiście wolę.
jesli pytasz na zasadzie samorozwoju: zmienić język, zainteresować się Kotlinem.
jesli korporacyjnej konieczności - nie dyskutuję z tym, mus to mus.
KamilAdam napisał(a):
To Java jest zła, bo rozwlekła.
Nie tylko w bezwzględnej długości kodu problem, to bym wybaczył, ale w zingnorowaniu istotnych potrzeb. *)
Np nigdy nie wyspecyfikowano syntaktycznie wydzielonej property / geterea / setera, i to co mamy to jest "by convention". A to zrobiło sie bardzo ważne przez Java Beany, "bardzo ważną rzecz" mamy by convention.
Libki próbujące z klasy "zgadnąć" strukturę/nazwę property/beanów każda robi to inaczej
Młodszy brat (C#) sie tym zajął i z propertisami jest bardzo dobrze
*)
choć nic nie równa się z komitetem standaryzującym C++
Czy Javę by ratowało (częściowe) zerwanie kompatybilnosci, np po 3 numerkach wersji / 10 latach odesłanie deprecated w kosmos ... może, ale tak nie jest.
programista60kPLN napisał(a):
Hej
W tutorialu, z które aktualnie się uczę jest stosowany Lombok, pozwala on zlikwidować część powtarzalnego kodu.
Spotkałem się z wieloma opiniami, że jednak lepiej z niego nie korzystać. Chciałbym poznać Wasze doświadczenia z tym projektem i opinie nt. tego, czy powinno się tym w ogóle interesować w 2022 roku.
Niektórzy programiści są zmuszeni pisać w Javie, bo np pracują nad projektem który jest napisany w Javie, a jednocześnie uważają że Java jest językiem syntax-heavy, to znaczy język w dużej mierze opiera się na składni, dla niektórych za dużej. Nie można sobie pozwolić na przepisanie aplikacji na inny język, więc takim "kompromisem" jest dodanie biblioteki (można powiedzieć "meta-programistycznej") które usuwa część składni i zastępuje je deklaratywnym podejściem.
Ja osobiście uważam, że lombok jest średnim rozwiązaniem, bo jeśli już ktoś chce odejść od składni Javy (która, no zgadzam się, jest dość verbose) to należałoby to zrobić w odpowiedni sposób, tzn wydzielić nowy moduł w projekcie, i nowe funkcjonalności pisać w innym jezyku który się kompiluje do JVM byte-code, np Clojure, Kotlin czy Groovy, które mają już przyjemniejszą składnię. I potem czasowo przechodzić z jednego języka w drugi. W mojej opinii lombok to jest taki "pół-środek", i ja wolałbym albo pisać w Javie bez lomboka, a jeśli składnia byłaby zbyt rozwkleła to przemigrowałbym powoli projekt np. na Kotlin.
Największym problemem lomboka dla mnie jest to że trzeba pamiętać która adnotacja co robi.
Poprawne wykorzystanie nie jest takie oczywiste.
W nowym projekcie zacząłem czasami korzystać z rekordów i póki co się sprawdzają.
Riddle napisał(a):
Ja osobiście uważam, że lombok jest średnim rozwiązaniem, bo jeśli już ktoś chce odejść od składni Javy (która, no zgadzam się, jest dość verbose) to należałoby to zrobić w odpowiedni sposób, tzn wydzielić nowy moduł w projekcie, i nowe funkcjonalności pisać w innym jezyku który się kompiluje do JVM byte-code, np Clojure, Kotlin czy Groovy, które mają już przyjemniejszą składnię
Ale wcale nie trzeba robić takich kombinacji. Bez problemu można zrobić konfigurację gdzie część klas jest napisana w Javie a część już po nowemu w Kotlinie/Scali
To ja pójdę w inną stronę. Lombok jest dla mnie nieproduktywny, a wynika to z arytmetyki pracy.
- Lombok zdejmuje z programisty pisanie boilerplate'u, to prawda. Czyli zysk jest jednorazowy.
- Natomiast późniejsza praca z kodem robi się problematyczna. Chcesz zapiąć się debugiem w setterze? No to musisz zmienić kod, lub wyłączyć kompilację przy uruchomieniu debugu. I jedno, i drugie jest uciążliwe. No i jest kwestia jakości pluginów do Lomboka - nie wiem, jak dzisiaj ale swego czasu nie dało się znaleźć wywołania np. lombokowego gettera w Idei.
- Kolejna rzecz to to, że Lombok jest jak granatnik na komendzie policji. Niby taka fajna i niegroźna zabawka, ale wystarczy nacisnąć nie tam, gdzie trzeba.
Według mnie pkt. 2 i 3 przeważają nad pkt. 1. Jeśli chcesz pisać w fajniejszym języku to korzystaj z Kotlina.
Lombok
- to taki język programowania który używasz, gdy już wiesz, że java
w pisaniu typowego kodu "enterprajs*
" strasznie obsysa, ale głupio Ci się do tego przyznać,
bo wszystkim mówiłeś jaka ta java
super. Do tego jesteś seniorem javy z co najmniej 3 miesiącami doświadczenia, głupio zaczynać ścieżkę kariery od nowa.
Lombok to nie jest java, bo:
a) javac tego nie kompiluje,
b) wymaga plugina do gradle/maven (tak jak każdy inny język),
c) wymaga plugina do IDE (tak jak każdy inny język),
d) trzeba się go nauczyć (jak każdego innego języka)
Lombok
jest co najwyżej javopodobny.
Lombok
mocno różni się od innych generatorów kodu, dlatego że podmienia klasy "in place" (dla wnikliwych: warto sprawdzić(!!!) - bo dokładnie to już nie pamiętam, co dokładnie robi, ale nie robi tego normalnie (i sorry, nie chce mi się teraz tego nawet czytać)). W przypadku innych generatorów (swagger itp.) odpalamy goal w mavenie/gradle i klasy (lub nawet źródła) lądują w target/generated_classes
czy tam target/generated_sources
- więc nadal radzi sobie z tym normalny javac/IDE.
Ten magiczny sposób działania powoduje czasem mocne bóle głowy, ale przede wszystkim powoduje, że kod, który piszemy nie jest kodem w javie, bo nie da się zrobić tak, żeby się kod kompilował w jakimkolwiek momencie.
Kod z lombokiem jest po prostu brzydki: mamy tony adnotacji przed każdą klasą, zwykle 3/4 z nich zupełnie niepotrzebna, na zapas, śmiecą. Trudno to posprzątać, bo trzeba by regularnie sprawdzać czy nadal jakaś adnotacja jest potrzebna (dla całego kodu - powodzenia).
2 razy miałem poważne problemy ze zlomboczonym kodem przy migrowaniu na nową wersję javy (niestety nie pamiętam co to było, ale kojarzę, że bolało, i że głownym problemem był ten magiczny sposób działania).
Zamiast babrać się w lomboka lepiej jest poświęcić ten czas na opanowanie normalnego języka programowania - najbliżej Kotlin lub Scala, będzie wszystko to co w lomboku, plus wiele innych przydatnych cech, a najważniejsze, że kod nie będzie tak obrzydliwy. Pomijająć już to, że składnia nowszych języków jest prostsza i bardziej logiczna od składni Javy.
*
Enterprajs = (prosta logika biznesowa, bazy danych, integracja systemów, resty)
Możliwe że to zależy od projektu albo domeny biznesowej. Pracowałem w projekcie, który był gigantycznym CRUD-em (kilkadziesiąt kontrolerów, totalne spaghetti) i tam Lombok, JPA, adnotacje na encjach, domyślna serializacja DTO -> JSON, wyciekanie modelu danych na front i wszystkie tego typu hejtowane "antypatterny" znakomicie usprawniały pracę, trzeba było tylko mieć trochę oleju w głowie i wiedzieć jak to działa pod spodem, jak i liczyć się z ewentualnymi konsekwencjami, które były minimalne - głównie coupling frontend-backend.
Miałem pewną programistyczną podróż podczas której inaczej spojrzałem na lomboka.
Wcześniej pracowałem w projektach w technologii Java EE, czyli często i gęsto używanie EJB i JPA. EJB wymagają domyślnego bezparametrowego konstruktora, beany są "stateless", więc te klasy miały tylko pola wstrzykiwane, brak "setterów" i "getterów". JPA też wymagają bezparametrowego konstruktora, "gettery" i "settery" każde IDE jest w stanie wygenerować, a nadpisywanie "equals" oraz "hashCode" w encjach JPA uważam za zło. Lombok w takim projekcie nie dawałby wielu korzyści, wręcz zacząłby przeszkadzać. Wtedy uważałem, że należy go unikać.
Następnie przerzuciłem się na projekty w technologii Spring. Jeśli encje bazodanowe pisało się w technologii innej niż JPA/Hibernate to można było pisać klasy niemutowalne, pola finalne, builder pattern łatwo wpasowywał się tutaj, a beany czy jak kto tam woli komponenty pozwalały na wstrzykiwanie poprzez konstruktor. Próbowałem bronić się przed tym ale lombok tutaj zaczął ułatwiać.
Nadal nie podoba mi się w jaki sposób działa lombok, że to nie jest generator kodu tylko manipulator bytecode'u, że jest tak powszechnie używany przez osoby, które nie rozróżniają tożsamości od równości obiektów. Użycie jednej adnotacji @Data
zamiast dwóch @Setter
i @Getter
bardzo dużo zmienia.
Wydaje mi się, że odpowiedź na pytanie zadane w temacie wątku jest taka: to zależy co umiesz i z kim pracujesz. Ja już mam postanowienie na nowy rok i planuję zacząć pracować w języku, który nie wymaga protez typu lombok.
Dla mnie, największe wady to:
- Nie wiadomo jak działa, nie wiadomo dlaczego działa, nie wiadomo kiedy przestanie działać. Może już poprawili implementację, ale właśnie z działaniem były problemy w przeszłości.
- Nieczytelność. Jakaś adnotacja w nagłówku klasy decyduje o tym, czy zmienna prywatna będzie widoczna, lub niewidoczna na zewnątrz.
- Jakaś inna adnotacja powoduje, że będzie wygenerowany equals i hashcode...
- Mocno randomowa funkcjonalność i mnogość adnotacji. Dlaczego akurat te, a nie inne? Nikt nie wie.
- Wynalazki w stylu
@SneakyThrows
... - Ogólnie, to narzędzie jest jak typowy Scrum Master - tworzy więcej problemów niż rozwiązuje. A te, które rozwiązuje są nie tyle tymi problemami, które naprawdę przeszkadzają, ale tymi, które dało się rozwiązać.
Dla mnie największe wady to używanie tego w klasach które są encjami bazodanowymi.
Google chyba też nie lubi Lomboka, bo pomimo tego że jest dostarczany z InteliJ, to z Android Studio wyleciał już dawno. .
@gajusz800: Nie wiem, czy Google nie lubi, czy lubi Lombok'a. W Androidzie, od lat podstawowym językiem jest Kotlin, w którym stosowanie protez w rodzaju Lomboka nie ma żadnego sensu. Jedyną zaletą tego narzędzia, jest mniej znaków w kodzie źródłowym. Samo-generujący się konstruktor, czy metody dostępowe oczywiście są jakimś tam ułatwieniem, ale to nie te dodatkowe metody na poziomie POJO są prawdziwym problemem podczas pisania oprogramowania. Zresztą, nawet jeżeli, nie wiem co tu porównywać..
Kotlin:
class Person(val name:String, val lastName:String, val yearOfBirth:Int? = null)
Lombokowana Java:
import lombok...
import lombok...
import lombok...
import lombok...
@Getter
@RequiredArgsConstructor
@AllArgsConstructor
public class Person{
@NonNull
private final String name;
@NonNull
private final String lastName;
private final int yearOfBirth;
}
I "pure"Java
public class Person{
private final String name;
private final String lastName;
private final int yearOfBirth;
public Person(String name, String lastName, int yearOfBirth){
if(name == null || lastName == null){
throw new NullPointerException("name and lastName cannot be null")
}
//to niżej i tak wygeneruje IDE...
this.name = name;
this.lastName = lastName;
this.yearOfBirth = yearOfBirth;
}
public Person(String name, String lastName){
this(name, lastName, null);
}
public String getName(){
return name;
}
public String getLastName(){
return lastName;
}
public String getYearOfBirth(){
return lastName;
}
}
Wiem, że podstawowym językiem jest Kotlin, ale Lombok został usunięty chyba jeszcze zanim to się zmieniło. Poza tym, nie zapominajmy że Java dalej jest obsługiwana i nigdzie się nie wybiera.
Ale przecież to tylko plugin w IDE. Jak ktoś bardzo potrzebuje, to może sobie go dociągnąć. Wciąż pozostaje pytanie, dlaczego miałbym decydować się na Lomboka w Androidzie, skoro, nawet w projekcie z Javą mogę sobie zamiast adnotacyjnego łamańca wstawić klasę w Kotlinie?
Ja z tobą nie polemizuję, tylko stwierdzam fakt, że ten plugin wyleciał z Android Studio, a InteliJ ma go w standardzie, jako wbudowany.
piotrpo napisał(a):
@gajusz800: Nie wiem, czy Google nie lubi, czy lubi Lombok'a. W Androidzie, od lat podstawowym językiem jest Kotlin, w którym stosowanie protez w rodzaju Lomboka nie ma żadnego sensu. Jedyną zaletą tego narzędzia, jest mniej znaków w kodzie źródłowym. Samo-generujący się konstruktor, czy metody dostępowe oczywiście są jakimś tam ułatwieniem, ale to nie te dodatkowe metody na poziomie POJO są prawdziwym problemem podczas pisania oprogramowania. Zresztą, nawet jeżeli, nie wiem co tu porównywać..
Kotlin:class Person(val name:String, val lastName:String, val yearOfBirth:Int? = null)
Lombokowana Java:
import lombok... import lombok... import lombok... import lombok... @Getter @RequiredArgsConstructor @AllArgsConstructor public class Person{ @NonNull private final String name; @NonNull private final String lastName; private final int yearOfBirth; }
I "pure"Java
public class Person{ private final String name; private final String lastName; private final int yearOfBirth; public Person(String name, String lastName, int yearOfBirth){ if(name == null || lastName == null){ throw new NullPointerException("name and lastName cannot be null") } //to niżej i tak wygeneruje IDE... this.name = name; this.lastName = lastName; this.yearOfBirth = yearOfBirth; } public Person(String name, String lastName){ this(name, lastName, null); } public String getName(){ return name; } public String getLastName(){ return lastName; } public String getYearOfBirth(){ return lastName; } }
Nie mam co porównywać:
public record Person(String name, String lastName, OptionalInt yearOfBirth) {
Person(String name, String lastName, OptonalInt.empty());
}
A Java 14 wyszła w marcu 2020 roku.
scibi_92 napisał(a):
A Java 14 wyszła w marcu 2020 roku.
No dobra, to skoro Java taka zajefajna, zwięzła i już ponad 2 lata ma 14'ka, to dlaczego dorzuca się do niej Lomboka? Może dlatego, że pierwsza wersja LTS która zawiera records pokazała się ledwo kilka miesięcy temu, a spora część javowego świata wciąż siedzi w 8.
Może pewnego dnia Java dorobi się named perameters, wymaganych lub nie? I nie będzie tych builderów paskudnych? Lub adnotacji @Builder
w Lombok. Do OptionalInt
zamiast Optional<int>
w Javie można się czepiać, ale tak samo można się czepiać że w C# nie ma string?
i string
(chyba że już jest, nie jestem na czasie). I czemu w C# przypisanie nulla do zmiennej non nullable to warning dopiero przy kompilacji? To powinno IDE podkreślić od razu na czerwono i nie powinno się to skompilować nawet.
No dobra, to skoro Java taka zajefajna, zwięzła
Literalnie nigdy nie napisałem że Java jest zwięzła. :) Po prostu odniosłem się do tego co napisałeś. Jak już Jave krytykujemy (a co jest chyba najczęstszym hobby użytkowników tego forum) to piszmy zgodnie z rzeczywistością :)
Znaczna część problemów której zarzucano Javie odeszła niedawno lub w niedalakiej przyszłosci zostanie odłożona do lamusa.
to dlaczego dorzuca się do niej Lomboka?
Mnie o to nie pytaj. Ja bym nie dorzucał ;]
a spora część javowego świata wciąż siedzi w 8.
Zapewne tak. Ja obecnie pisze nowy serwis i nie jest to Java 8. Myślę że mimo wszystko łatwiej znaleźć prace na backendzie w Javie 17+ niż z Kotlinem.
Myślę że mimo wszystko łatwiej znaleźć prace na backendzie w Javie 17+ niż z Kotlinem
Twoje myśli to nie dowód :P a ja zna kogoś kto na backendzie pisał projekt w Kotlinie. I znam kogoś kto na backendzie pisał projekt w Scali. Jak znajdziesz kogoś kto pisał na backendzie projekt w Javie 17+ to daj znać :D
UPDATE a teraz będę wrednym człowiekiem i powiem
class Person(var name:String, var lastName:String, var yearOfBirth:Option[Int] = None)
XD
Jak z jakiegoś chorego powodu chcesz mutowalne obiekty to rekordy w Javie nie pomogą, co nie? XD
Jak znajdziesz kogoś kto pisał na backendzie projekt w Javie 17+ to daj znać :
Daję
Twoje myśli to nie dowód :P
Moje myślenie jest oparte o znajomośc rynku i ofert. Sam kiedyś chcialem przejsc na Kotlina, teraz za bardzo już nie odczuwam takiej potrzeby
Jak z jakiegoś chorego powodu chcesz mutowalne obiekty to rekordy w Javie nie pomogą, co nie? XD
Nie.
Ale ten temat to roast Lomboka, a nie Javy.
Porównanie ze "starą" Javą i Kotlinem zrobiłem bo:
- W nowej Javie Lombok ma jeszcze mniej sensu
- Wprowadzenie w Javie 8 Lomboka/Kotlina jest znacznie prostsze niż przejście na Javę 19...
- Wybranie Kotlina jako dodatkowego języka w projekcie J8 nie jest trudniejsze niż wprowadzenie lomboka.
Kotlin/Scala > Java 17 + Lombok > Java 17 > Java 8 + Lombok > Java 8 > Groovy > Java 7
Czyli cała dyskusji rozchodzi się o learning curve i zdolność organizacji do zaakceptowania nowinek.
Learning curve dla Lomboka jest bardzo mały - dużo mniejszy niż np dla takiego MapStruct. Annotacje wyglądają paskudnie, ale zawsze to lepiej niż pisać ręcznie equals dla klas.
Ja jeszcze dodam, że @Slf4j rozwiązuje bikeshedding o to, jak nazywać to coś LOG, LOGGER, log, czy logger, i czy powinna to być pierwsza deklaracja static.
Generalnie to mocno nie szanuję firm które w 22 piszą nowe projekty w Javie a nie Kotlinie. Świadczy to o jakimś strachu przed technologią i niechęci ich pracowników do nauki.
Rakieta napisał(a):
Generalnie to mocno nie szanuję firm które w 22 piszą nowe projekty w Javie a nie Kotlinie. Świadczy to o jakimś strachu przed technologią i niechęci ich pracowników do nauki.
W sumie to ja też nie szanuję zasiedzianych seniorów u mojego obecnego pracodawcy :) Nie podnosiłem tematu Kotlina, bo już całą moją reputację zużyłem na takie pierdoły jak Lombok.