Co jest nie tak z tym kodem?

Co jest nie tak z tym kodem?
XL
  • Rejestracja:prawie 8 lat
  • Ostatnio:około 6 lat
  • Postów:58
0

Hej,

Poniższy fragment kodu został odrzucony na code review. Czy możecie mi powiedzieć co jest z nim nie tak? Komentarz recenzenta na razie przemilczę.

Kopiuj
    private User getUser(long userId) {
        User user = userRepository.findById(userId);
        if (user == null) {
            throw new ResourceNotFoundException("User with id: " + userId + " not found.");
        }
        return user;
    }
szweszwe
  • Rejestracja:ponad 11 lat
  • Ostatnio:4 dni
  • Lokalizacja:Kraków
  • Postów:1694
0

A to w ogóle nie jest Unhandled exception?

XL
  • Rejestracja:prawie 8 lat
  • Ostatnio:około 6 lat
  • Postów:58
0

Jest to custom RuntimeException.

0

Zakładam że jest to metoda z jakiegoś @Controllera więc z tego co czytałem na forum nie może zwracać encji - ale mogę się mylić :D

EP
  • Rejestracja:prawie 8 lat
  • Ostatnio:ponad 6 lat
  • Postów:122
0

Być może musisz zwrócić jakieś DTO, zamiast bezpośrednio obiektu z repozytorium?


Wenn ist das Nunstück git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!
Prędki_Lopez
  • Rejestracja:ponad 9 lat
  • Ostatnio:około 5 godzin
  • Postów:251
0

Wydaje mi się, że istotny jest kontekst w jakim ta metoda jest tworzona. Gdzie ją tworzysz? Btw. Jaki komentarz dał ? :)

Edit: Sokoloki. Czy tu nie chodzi o prywatny getter? Dane pobrane z bazy prawdopodobnie chcesz przekazać dalej.
Edit2: Optionala możesz użyć.

Swoją droga fajny code review jak Ci nie mówią co jest źle

edytowany 4x, ostatnio: Prędki_Lopez
XL
komentarz jest, ale ujawnię go później - pisałem o tym w pierwszej wiadomości
katelx
  • Rejestracja:prawie 10 lat
  • Ostatnio:4 miesiące
  • Lokalizacja:Hong Kong
0

po co w ogole ta metoda zamiast po prostu uzywac userRepository.findById(userId) :)

Zobacz pozostałe 3 komentarze
Prędki_Lopez
jakby co to nie bylo pytania, cos mi się pomerdało, zmęczony już
katelx
spoko, ale pewnie i tak bym nie odpowiedziala bo nie znam zbytnio wzorcow zwiazanych z repozytoriami
Prędki_Lopez
Na moje to Optionala zwrócić i go sprawdzać potem czy jest pusty, ale są takie momenty chyba kiedy chcemy rzucić po prostu wyjątek jesli nie znajdziemy wymaganych danych w bazie.
katelx
nie lubie wyjatkow poza rzeczywiscie powaznymi sytuacjami bo szybko sie robi z tego instrukcja sterujaca. w wypadku takim jak tutaj zgadzam sie co do optionala + nazwe metody na tryFindById zeby od razu bylo widac ze spodziewamy sie faila
vpiotr
Kupę lat temu stosowałem takie nazewnictwo: getById() / checkById() - wywal wyjątek jak nie ma, findById() - zwróć null. W szczególności jedno wołało drugie, ale obsługa nulla była w jednym miejscu.
S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:5 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
4

@xLatency: kurde żyjemy w 2017 roku, Java 8 ma 3 lata a dalej się nie nauczyli że z DAO/Repository jak zwracamy encje której może nie byc to zwracamy Optional?
Kurde heloł ludzie Java 9 za kilkadziesiąt dni (mam nadzieje :D ) a dalej nie umiecie into Java 8? oO


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
katelx
java 9 juz za kilkaset dni ;) poza tym nie badz swinia, niektorzy nie wyszli ponad jave 7 :(
jarekr000000
Und dort liegt der Hund begraben
S9
@jarekr000000: czy dobrze google translator mi tłumaczy "i tu jest pies pogrzebany"?
0
scibi92 napisał(a):

@xLatency: kurde żyjemy w 2017 roku, Java 8 ma 3 lata a dalej się nie nauczyli że z DAO/Repository jak zwracamy encje której może nie byc to zwracamy Optional?
Kurde heloł ludzie Java 9 za kilkadziesiąt dni (mam nadzieje :D ) a dalej nie umiecie into Java 8? oO

Czasami wole zwyklego null checka niż przeginanie z Optionalami.

jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:10 minut
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4707
2

Problem zależy od kontekstu , ale kod generalnie useless - SpringData od dawna zwracać może Optionale. Wiec po co robić takie nonsensowne przepakowywanie - jak można u źródła naprawić.


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 2x, ostatnio: jarekr000000
YA
  • Rejestracja:prawie 10 lat
  • Ostatnio:około 4 godziny
  • Postów:2368
0

Zamieniasz nulla na wyjątek. Zarówno nulla jak i wyjątek trzeba obsłużyć w logice, która korzysta z tej metody.
Gdzie widzisz wartość z tej konwersji?

Możliwe, że chodzi o uniknięcie duplikacji kodu, ale oznaczałoby, że w ramach klasy często korzystasz z getUser(). Jeśli tak, to może klasa powinna odstawać na wejściu Usera, a nie pobierać go sobie z repozytorium? Nie wiedzę całej klasy, więc bez kontekstu ciężko ocenić czy taka konstrukcja ma jakiekolwiek zalety.

vpiotr
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 3 lata
1
yarel napisał(a):

Zamieniasz nulla na wyjątek. Zarówno nulla jak i wyjątek trzeba obsłużyć w logice, która korzysta z tej metody.

Błąd - wyjątków nie trzeba.
Cała zaleta wyjątków (której niestety wielu nie rozumie) polega na tym że ich nie trzeba od razu obsługiwać.
Nawet nie jest to zalecane.

https://softwareengineering.stackexchange.com/questions/231057/exceptions-why-throw-early-why-catch-late

2
vpiotr napisał(a):
yarel napisał(a):

Zamieniasz nulla na wyjątek. Zarówno nulla jak i wyjątek trzeba obsłużyć w logice, która korzysta z tej metody.

Błąd - wyjątków nie trzeba.
Cała zaleta wyjątków (której niestety wielu nie rozumie) polega na tym że ich nie trzeba od razu obsługiwać.
Nawet nie jest to zalecane.

https://softwareengineering.stackexchange.com/questions/231057/exceptions-why-throw-early-why-catch-late

Mozna rzucac wyjatek i lapac w exception mapperze czy tam controlleradvice i zamieniac na response.

S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:5 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
0

Bzdura że wyjątek trzeba obslugiwac w samym kodzie(chyba że to tzw. checked exception). Możesz dodać w Springu ExceptionHandlery ktore zwrocą ci np. kod błędu albo przekierują na inną stronę
ale wystarczy że masz taki interceptor a gdy go zarejestrujesz to gdziekolwiek wyrzucony błąd trafi do tego interceptora jeśli sam tego nie obsłużysz


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
YA
  • Rejestracja:prawie 10 lat
  • Ostatnio:około 4 godziny
  • Postów:2368
0
vpiotr napisał(a):
yarel napisał(a):

Zamieniasz nulla na wyjątek. Zarówno nulla jak i wyjątek trzeba obsłużyć w logice, która korzysta z tej metody.

Błąd - wyjątków nie trzeba.
Cała zaleta wyjątków (której niestety wielu nie rozumie) polega na tym że ich nie trzeba od razu obsługiwać.
Nawet nie jest to zalecane.

https://softwareengineering.stackexchange.com/questions/231057/exceptions-why-throw-early-why-catch-late

Może mam spaczone spojrzenie, ale wg mnie wyjątek służy do zasygnalizowania nietypowej sytuacji i jest to tylko mechanizm (podobnie jak mechanizmem jest zwracanie kodu błędu przez funkcję). Jak coś informuje o sytuacji nietypowej, to trzeba to obsłużyć, ale gdzie i w jaki sposób, to zależy od sytuacji ;-)

Czy to będzie wpis do logu, czy wyświetlenie użytkownikowi komunikatu, czy zdefiniowanie jakiegokolwiek handlera - jest to nadal obsługa.

Wracając do przykładu, metoda jest prywatna, więc jak zmieni się implementacja getUser i nie będzie rzucanego wyjątku, to jest sens go obsługiwać gdzieś "wyżej" ? :)

-- edycja:
Dodam jeszcze, że w przypadku braku użytkownika rzucanie wyjątku o wdzięcznej nazwie ResourceNotFound razi w oczy. Czemu nie UserNotFound?

edytowany 1x, ostatnio: yarel
0
Krzywy kr napisał(a):
vpiotr napisał(a):
yarel napisał(a):

Zamieniasz nulla na wyjątek. Zarówno nulla jak i wyjątek trzeba obsłużyć w logice, która korzysta z tej metody.

Błąd - wyjątków nie trzeba.
Cała zaleta wyjątków (której niestety wielu nie rozumie) polega na tym że ich nie trzeba od razu obsługiwać.
Nawet nie jest to zalecane.

https://softwareengineering.stackexchange.com/questions/231057/exceptions-why-throw-early-why-catch-late

Mozna rzucac wyjatek i lapac w exception mapperze czy tam controlleradvice i zamieniac na response.

Jeszcze tylko dodam, ze raczej nie powinno sie rzucac wyjatki na poziomie DAO i lapany gdzies w exception mapperze i zmieniany na response ;)

Tylko gdzies po drodze taki wyjatek z dao powinien byc owrapowany jakims serwisowym.

nie100sowny
  • Rejestracja:prawie 9 lat
  • Ostatnio:dzień
  • Lokalizacja:Kraków
  • Postów:402
0

Sporo bzdur się pojawia. Więc postaram się skonfrontować moje poglądy.

Wyjątek checked rzucamy w sytuacji błędu gdy bezpośredni kod wywołujący jest w stanie zareagować/naprawić/ponowić wywołanie.

Unchecked exception, rzucamy gdy kod wywołujący nie jest w stanie nic zrobić z wyjątkiem.

Wyjątki są kosztowne. Wymagają zbudowania stacktrace. Są rzadkie statystycznie i JIT ich nie optymalizuje. Dlatego prowadzenie logiki wyjątkami jest słabe. Szczególnie gdy nasz system jest pod dużym obciążeniem. Wówczas pojawiają się wyjątki np. Timeouty co dodatkowo zabija system. Czyli w kryzysie wolne wyjątki dodatkowo dobijają system.

Czasem w ENTERPRAJS systemach rzuca się unchecked wyjątki wszędzie. Dzięki czemu mamy mniej ifów. A w jakimś aspekcie/advice/filtrze te wyjątki mapuje na błędy HTTP. O ile nasza aplikacja obsługuje 2 userów na godzinę to można to przeżyć. Nadaje się to do CRUDowych i watstwowych aplikacji. Osobiście jednak odradzam.

Najlepiej projektować kod tak, aby system zwracał wynik zawsze. Przydatne klasy to Optional/Either. RxJava, która zmusza do pomyślenia o błędach.

Pomysł z przepakowywaniem wyjątków to tragedia - techniczny kod który nic nie robi, a jedynie zadowala ego programisty.

Wyjątek per zasób to również niepotrzebny bojilerplate.

W skrócie nie rzucaj wyjątków stosuj Optional/Either. I projektuj system w którym gdy poleci unchecked exception to oznacza to konieczność zmiany środowiska/konfiguracji/kodu. W dobrej aplikacji wyjątki nie latają.


"Gdy się nie wie, co się robi, to się dzieją takie rzeczy, że się nie wie, co się dzieje"
vpiotr
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 3 lata
1

Ten kod może być dobry lub zły - w zależności od architektury.

Sytuacje w zasadzie są możliwe dwie:
a) obiekt jest wymagany
b) obiekt jest opcjonalny

W przypadku (b) gdy jest opcjonalny (bo np. nie wiesz czy podany w ciasteczku user nie został usunięty przez ostatnie 60 dni) to można stosować null lub Optional i gdzieś tam dalej to jakoś obsłużyć logiką biznesową.

W przypadku (a) gdy jest wymagany (bo np. szukasz usera który właśnie został zalogowany albo którego właśnie udało Ci się dodać do bazy) to bzdurą jest tworzenie jakiejkolwiek logiki do obsługi takich sytuacji gdy jednak go nie znaleźliśmy.
Wtedy rzucasz wyjątek i obsługujesz to jako błąd którego nie można przewidzieć, np. "odłączono drukarkę w trakcie drukowania raportu", "dysk ktoś zapełnił procesem idącym równolegle", "ktoś przeciął siekierą kabel sieciowy" albo... "ktoś puścił delete po całej bazie w trakcie procesu".
Gdzie tą obsługę dajesz i na ilu poziomach ten błąd przepakowujesz (o ile wiesz po co to robisz) to już szczegół techniczny.
Ale zwykle nie jest to poziom bezpośrednio sąsiadujący, bo wtedy równie dobrze moglibyśmy się cofnąć do czasów C i kodów powrotu.

A dlaczego ten kod został odrzucony? Jest kilka możliwości:

  • nie ta klasa wyjątku - np. zbyt ogólna lub niezgodna ze standardami
  • user jest opcjonalny, czyli błąd jest natury logicznej i trzeba go obsłużyć biznesowo
  • user jest wymagany, ale jesteś w EJB i np. może być niewygodny fakt że zrobi się przez to rollback
  • komunikaty zwykle są tłumaczone na konkretny język, a tu nie masz kodu błędu/wiadomości

Kilka zasobów:
https://www.ibm.com/developerworks/library/j-ejbexcept/index.html
(autoreklama) http://www.foundbit.com/pl/zasoby/jezyki/java/zaawansowane/articles/java-wyjatki.html

jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:10 minut
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4707
0
vpiotr napisał(a):

W przypadku (b) gdy jest opcjonalny (bo np. nie wiesz czy podany w ciasteczku user nie został usunięty przez ostatnie 60 dni) to można stosować null lub Optional i gdzieś tam dalej to jakoś obsłużyć logiką biznesową.

No nie ucz mi dzieci takich rzeczy. Jak obiekt jest opcjoinalny to się używa Optional. null w kodzie biznesowym nie powinien sie pojawiać (awruk!).
(jak ktoś robis jakieś obliczenia na macierzach i walczy o cykle to jeszcze można zdzierżyć).


jeden i pół terabajta powinno wystarczyć każdemu
vpiotr
Ta, na pewno w obliczeniach na macierzach masz nulle :)
0
nie100sowny napisał(a):

Sporo bzdur się pojawia. Więc postaram się skonfrontować moje poglądy.

Wyjątek checked rzucamy w sytuacji błędu gdy bezpośredni kod wywołujący jest w stanie zareagować/naprawić/ponowić wywołanie.

Unchecked exception, rzucamy gdy kod wywołujący nie jest w stanie nic zrobić z wyjątkiem.

Wyjątki są kosztowne. Wymagają zbudowania stacktrace. Są rzadkie statystycznie i JIT ich nie optymalizuje. Dlatego prowadzenie logiki wyjątkami jest słabe. Szczególnie gdy nasz system jest pod dużym obciążeniem. Wówczas pojawiają się wyjątki np. Timeouty co dodatkowo zabija system. Czyli w kryzysie wolne wyjątki dodatkowo dobijają system.

Czasem w ENTERPRAJS systemach rzuca się unchecked wyjątki wszędzie. Dzięki czemu mamy mniej ifów. A w jakimś aspekcie/advice/filtrze te wyjątki mapuje na błędy HTTP. O ile nasza aplikacja obsługuje 2 userów na godzinę to można to przeżyć. Nadaje się to do CRUDowych i watstwowych aplikacji. Osobiście jednak odradzam.

Najlepiej projektować kod tak, aby system zwracał wynik zawsze. Przydatne klasy to Optional/Either. RxJava, która zmusza do pomyślenia o błędach.

Pomysł z przepakowywaniem wyjątków to tragedia - techniczny kod który nic nie robi, a jedynie zadowala ego programisty.

Wyjątek per zasób to również niepotrzebny bojilerplate.

W skrócie nie rzucaj wyjątków stosuj Optional/Either. I projektuj system w którym gdy poleci unchecked exception to oznacza to konieczność zmiany środowiska/konfiguracji/kodu. W dobrej aplikacji wyjątki nie latają.

Wiadomo, że obecnie najlepiej zawsze zwracać wynik. Ja tylko podałem przykład, w nawiązaniu do czyjegoś posta ' co można zrobić'. Nie powiedziałem, że to jest słuszna droga. I nie ma lepszych. Przecież zawsze wszystko zależy od sytuacji i systemu w której pracujesz. Wiekszość systemów z jakimi pracujemy to te wlasnie ENTERPRAJS. Przepiszesz to wszystko z dnia na dzień by było w ogóle reactive, z circuit brakerami itp. ? Nie sądze ;) Zluzuj.

A odnośnie przepakowywania wyjątków to się nie zgodzę.Jak rzucasz wyjątek bazodanowy i go mapujesz na response to dla mnie jest to błąd architektoniczny. Bo co ma ten wyjątek wspólnego z RESTem ? Wszystko oczywiście zależy od architektury.

1

ee coś mi czcionkę powiększyło. przepraszam.

XL
  • Rejestracja:prawie 8 lat
  • Ostatnio:około 6 lat
  • Postów:58
0

Hej,

Dzięki za odpowiedzi. Zarzutem tutaj był null check zamiast użycia optionala.

Dyskusja jest ciekawa, dlatego pozwolę sobie pociągnąć wątek dalej.
Metoda getUser została wprowadzona dlatego że kilka razy w kodzie odpytuję o tego usera w różnych miejscach - dokładnie 3 razy.

Null check był po to, żeby nie rzucać null pointerem do klienta, tylko wysłać mu konkretną informację. Exceptiony są mapowane na response za pomocą ControllerAdvice.

Jeśli teraz zrobię sobie w Spring Data metodę findById:

Kopiuj
Optional<User> findById(long id)

To jak byście to obsłużyli w kontrolerze. Załóżmy że dalej mamy naszą metodę getUser

Kopiuj
 private User getUser(long userId) {
        return userRepository.findById(userId).orElseThrow(new ResourceNotFoundException("User with id: " + userId + " not found."));
 }

czy może tak:

Kopiuj
 private User getUser(long userId) {
        return userRepository.findById(userId).get();
 }

Abstrahując już od tego czy metoda getUser ma w takim przypadku sens czy nie.

A może faktycznie nie robić żadnego checka na nulla i zrobić jak już ktoś proponował :

Kopiuj
User findById(long id)

i w kodzie po prostu

Kopiuj
User user = userRepository.findById(id);
//operacje na user - możliwe NullPointer

PS. Prosiłbym również o zachowanie jakiegoś minimum kultury osobistej w wypowiedziach, bo niektóre odpowiedzi ocierają się o pyskówkę.

S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:5 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
1

Oczywiście jeżeli mamy Optional to nie powinien być pobrany obiekt bez sprawdzenia czy on istnieje, więcz pobranie opcjonala i od razu używania get to jest bardzo zły kod.

@nie100sowny no nie zgadzam się. Wyobraź sobie że na przykład masz operację logowania, koleś wpisuje zły login. Złe dane wejściowe to też może być powód do rzucenia wyjątkiem i średnio mi się widzi sprawdzanie po iluś metodach czy jest użytkownik czy go nie ma, jeśli będzie rzuczony wyjątek a interceptor to złapie to znacznie zwiększa czytelnośc kodu.


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
edytowany 1x, ostatnio: scibi92
0
scibi92 napisał(a):

Oczywiście jeżeli mamy Optional to nie powinien być pobrany obiekt bez sprawdzenia czy on istnieje, więcz pobranie opcjonala i od razu używania get to jest bardzo zły kod.

@nie100sowny no nie zgadzam się. Wyobraź sobie że na przykład masz operację logowania, koleś wpisuje zły login. Złe dane wejściowe to też może być powód do rzucenia wyjątkiem i średnio mi się widzi sprawdzanie po iluś metodach czy jest użytkownik czy go nie ma, jeśli będzie rzuczony wyjątek a interceptor to złapie to znacznie zwiększa czytelnośc kodu.

Nie popadajmy w skrajnosc. Mysle, ze @nie100sowny tez nie mial na mysli, zeby zwracac cos ZAWSZE. Chociaz teoretycznie moglbys zamiast rzucac UserNotFoundException to zwrocic jakiegos dummy usera ;) ale w przypadku logowania to raczej sytuacja wyjatkowa. Co innego jak siegamy do bazy po newralgiczne dane a co innego jak wyciagamy jakies zwyczajne dane.

W Golangu nie ma exceptionow. Erorr to value. Mozna zwracac z funkcji multiple values i sprawdzac czy error jest nil. Czego jest pelno w kodzie Go. Jednym sie to podoba. Innym nie ;) ma to jednak swoje zalety.

0

Mysle, ze piszac bardziej funkcyjnie czy reaktywnie to.... koncept javowych wyjatkow zwyczajnie do tego stylu nie pasuje

SP
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 2 lata
  • Postów:127
0
Krzywy kr napisał(a):

Mysle, ze piszac bardziej funkcyjnie czy reaktywnie to.... koncept javowych wyjatkow zwyczajnie do tego stylu nie pasuje

No tak średnio, bo czasem trzeba łapać wyjątek w lambdzie i trochę słabo to wygląda.

W JEE wygodnie jest oznaczać własne wyjątki adnotacją @ApplicationException, wtedy podczas wystąpienia nie są one ubierane dodatkowo w EJBException

edytowany 3x, ostatnio: student pro
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:10 minut
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4707
0
student pro napisał(a):

No tak średnio, bo czasem trzeba łapać wyjątek w lambdzie i trochę słabo to wygląda.

W JEE wygodnie jest oznaczać własne wyjątki adnotacją @ApplicationException, wtedy podczas wystąpienia nie są one ubierane dodatkowo w EJBException

Pod względem wyjątków JavaEE to mistrzostwo świata (biedy).
Wystarczy zapomnieć o tym ApplicationException, i mimo, że Ci się wydaje, że obsługujesz wyjątek w catch to i tak rollback leci (do tego na koniec transakcji poza twoim kodem, żeby było łatwiej).

Do tego nie zawsze, ważne, żeby interceptor go przyczaił (czyli jeśli poleci z wywoałania prywatnej metody to problemu nie ma). Zawsze mnie rozbija jak widze jak ktoś z tym walczy. Tej koncepcji nie da się wytłumaczyć człowiekowi przyzwyczajonemu, że catch robi po prostu catch i wyjątek obsługuje (co za dziwny pomysł w ogóle :-) ).

Tak ogólnie to o wyjątkach - zwłaszcza checked najlepiej juz zapomnieć (tzn. nie tworzyć nowych - co najwyżej żyć z tymi, które są w starym kodzie).
Koncepcja Try, Either lub Optional jest zdecydowanie wygodniejsza/ bezpieczniejsza - mimo, że na pierwszy rzut oka może się to wydawać to samo.
Tu i tu nas kompilator zmusza do "obsługi" problemu jeśli coś z innej metody wyciągamy.
Checked Exception wymusza catch, a optional .map lub .orElse. (Bo .get nie używamy!! jak pisał @Koziołek https://koziolekweb.pl/2017/08/07/kiedy-wypakowac-optional/).

To gdzie jest różnica?
Ano w tzw. referential transparency - Optional (czy inne monady) to po prostu wartość i można z tym pracować jak z każdą zmienną, a Exception to taki dziwny wybuch idący gdzieś poza kodem - zupełnie innym torem.

Gdzie to da się docenić ?
Pierwsze miejsce to Testy - zamiast dziwacznego sprawdzania wyniku z @Test(expected = NullPointerException ) czy innych cudów - robimy
ładne equals :
assertEquals ( Option.none(), repo.getUser("1234");
W testach "parametrycznych", w szczególnośc w Junit 5 to jest super.

Drugie miejsce to fakt, że teraz możemy nasze "wyjątki" nie tylko propagować "w górę" (czyli kto nas wywołał to dostanie), ale również
przekazywać innym !
Załóżmy, że mamy metodę repo.gimmeAllBros() która zwraca listę użytkowników systemu. I robimy jakiegoś batcha, który co noc bierze wszystkich userów i im wysyła spam :-).

Załóżmy, że to dziwny stary system i aby zebrać dane takiego gościa, to trzeba odpytać kilka baz - nie zawsze się udaje. Zwracamy Either dla każdego.
(załadował się ok, albo byl bład wtedy tylko dajemy Identyfikator).

Ta metoda może mieć postać:
List<Either<Integer, Person>> gimmeAllBros();
I mozemy sobie napisać :

Kopiuj
List<Either<Int, Person>>  all = repo.gimmeAllBros();
spamThem(all);
recalculateTheirMoney(all);

I teraz metoda spamThem może olać to, że niektórzy nie są znalezieni. No bo to tylko spam.
Ale metoda recalculateTheirMoney, która np. nalicza nowy stan konta musi zareagować i wysłać adminowi, że takich użytkowników konta były nie do ogarnięcia (i tu np. identyfikatory).

Czyli w pewnym sensie możemy propagować wyjątek w drugą stronę(w dół wywołań) i teraz to te wywołane metody są odpowiedzialne, za to żeby ewentualnie zareagować.


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 1x, ostatnio: jarekr000000
0

@jarekr000000:
Try to masz na mysli ten z javaslang?

jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:10 minut
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4707
0

Tak . Try z JavaSlang. (⋁⋀⋁⎧ ).To na współpracę ze starym kodem który rzuca exceptionami. Try pozwala to opakować (jako tako - nadal będzie troche brzydki).
W nowym kodzie Either lub Option.


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 1x, ostatnio: jarekr000000
0
jarekr000000 napisał(a):

Tak . Try z JavaSlang. (⋁⋀⋁⎧ ).To na współpracę ze starym kodem który rzuca exceptionami. Try pozwala to opakować (jako tako - nadal będzie troche brzydki).
W nowym kodzie Either lub Option.

A jak proponujesz ubsluzyc wspomniane cos w stylu UserNotFoundException przy logowaniu? ;)

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)