Jak żyć bez wyjątków i bez Either

Odpowiedz Nowy wątek
2019-08-29 07:18

Rejestracja: 1 rok temu

Ostatnio: 1 rok temu

0

Witam,
W związku z licznymi postami żeby nie rzucać wyjątków na prawo i lewo to pytanie jak sobie z tym radzić ? Dodam że sposób z Either znam ale załóżmy ze nie można go wykorzystać.

Mamy przykład

public User addUser(User user) throw Exception{
        if (user.getName < 3 ) {
            throw new Jakiś tam Exception(z opsiem)
        }
       return userRepo.add(user)
    }

Jeżeli nie chcemy rzucać wyjątku, to co powinniśmy zwracać w takim serwisie ? Klase np UserResponse która ma pola User, Error i na jej podstawie później mapować na HttpResponse?
Coś nie mogę znaleźć odpowiedniego repo żeby podglądnąć jak z tym sobie poradzić

Pozostało 580 znaków

2019-08-29 07:41

Rejestracja: 6 lat temu

Ostatnio: 4 godziny temu

Lokalizacja: Wrocław

1
  1. Wyjątek
  2. Either/Try
  3. Własny obiekt z miejscem na dobrą i błędną odpowiedź

Tutaj zakładam, że chodziło o minimalną długość imienia (nie wiem czemu, przecież są takie imiona), więc fajnie by było wiedzieć czemu zwrócono błąd ('za krótkie imie'). Da się to uzyskać każdym sposobem, więc jak Ci wygodniej/jakie są ustalenia na projekcie


"We don’t use Spring, because debugging annotation-driven problems is not fun," said Grzesik
4. Osobne obiekty reprezentujące różne odpowiedzi + polimorfizm. - Michał Sikora 2019-08-29 08:17

Pozostało 580 znaków

2019-08-29 07:53

Rejestracja: 13 lat temu

Ostatnio: 8 godzin temu

0

Można użyć wyjątku, czemu nie?To że ludzie nadużywają ich i komplikują kod to inna sprawa. Jednak w tym wypadku taka walidacja powinna zajść w konstruktorze klasy User.
Można też użyć Optional.


edytowany 1x, ostatnio: elwis, 2019-08-29 07:55

Pozostało 580 znaków

2019-08-29 08:01

Rejestracja: 6 lat temu

Ostatnio: 4 godziny temu

Lokalizacja: Wrocław

0
elwis napisał(a):

Można użyć wyjątku, czemu nie?To że ludzie nadużywają ich i komplikują kod to inna sprawa. Jednak w tym wypadku taka walidacja powinna zajść w konstruktorze klasy User.
Można też użyć Optional.

Takie akcje to lepiej w jakiejś statycznej fabryce + prywatny czysty konstruktor. Co do optionala to sie nie dowiesz dlaczego wystąpił błąd


"We don’t use Spring, because debugging annotation-driven problems is not fun," said Grzesik

Pozostało 580 znaków

2019-08-29 08:13

Rejestracja: 13 lat temu

Ostatnio: 8 godzin temu

0

@baant: jaki masz argument za fabryką? Nie widzę problemu żeby rzucić wyjątek w konstruktorze. Dla bardziej złożonego przypadku można użyć Buildera.
Co do braku komunikatu o błędzie, w rzeczy samej trzeba by było sprawdzać wynik, trochę bez sensu.


Pozostało 580 znaków

2019-08-29 08:16

Rejestracja: 6 lat temu

Ostatnio: 4 godziny temu

Lokalizacja: Wrocław

0

Po prostu wole jak konstruktor nie robi nic więcej poza konstruowaniem obiektu


"We don’t use Spring, because debugging annotation-driven problems is not fun," said Grzesik
Widzisz,a ja wolę wiedzieć że jeśli konstruktor się wykonał to mam poprawny obiekt - elwis 2019-08-29 14:13
Ja wolę, gdy poza obiektem leci wyjątek, by w konstruktorze było jak najmniej logiki. Jeśli tam zbiera się logika to wtedy ciężej wygląda z klasami, które to dziedziczą. - nohtyp 2019-08-29 15:44

Pozostało 580 znaków

2019-08-29 08:31

Rejestracja: 1 rok temu

Ostatnio: 1 rok temu

0

Tutaj zakładam, że chodziło o minimalną długość imienia (nie wiem czemu, przecież są takie imiona),

To tylko przykład. Nie zwracałem uwagę co tam ma być. Chodziło mi tylko że przy najprostszej walidacji rzucam wyjątek. I tak mam np klasę, która sprawdzą walidacje usera i chciałbym wiedzieć co dokładnie ma nie tak. Złe imie: leci wyjątek że złe imie, krótkie hasło: leci wyjątek że krótkie hasło. (Ten sam wyjątek tylko z inną wiadomością)

Either/Try

Vavr własnie chciałem ominąć. Chciałem wiedzieć jak sobie dobrze z tym poradzić bez tej biblioteki. Nie zawsze można jej użyć a i dawniej jej nie było, więc trzeba było bez tego dobrze kodzić.

Własny obiekt z miejscem na dobrą i błędną odpowiedź

To własnie mi chodzi po głowie tylko nie byłem przekonany do tego pomysłu. Nie wiedzialem czy to słuszne podejście.

Jednak w tym wypadku taka walidacja powinna zajść w konstruktorze klasy User.

W sumie masz rację.

Głównie mi chodzi o podejście jak uniknąć rzucania wyjątków przy walidacji bądź innych prostych rzeczach które naturalnie mogą wystąpić. Np Uniknąć UserNameNotFoundException gdy usera nie ma w bazie. Póki co to przychodzi mi do głowy to co wyżej pisałem: Własny obiekt z miejscem na dobrą i błędną odpowiedź. Taki ubogi Either.

zawsze możesz napisać własny either :) - baant 2019-08-29 08:36
+1 za własny Either. Jak można, to warto libki użyć, ale sama implementacja raczej bardzo trudna nie jest. - Klojtex 2019-08-29 17:58

Pozostało 580 znaków

2019-08-29 08:36

Rejestracja: 12 lat temu

Ostatnio: 7 godzin temu

1

Rzuć własny wyjątek, mapowanie na response zrób za pomocą @ControllerAdvice jeśli korzystasz ze Springa. Jeśli nie korzystasz, to własny mapper na poziomie warstwy web.


IT mikromenadżer
Jak przeglądam ile magii posiada @ControllerAdvice, na przykład All such beans are sorted based on @Order semantics and applied in that order at runtime. to już chyba lepiej nulla zwracać :) - DisQ 2019-08-29 09:44
Używamy masowo produkcyjnie i nigdy nie było problemów - Charles_Ray 2019-08-29 12:17

Pozostało 580 znaków

2019-08-29 09:50

Rejestracja: 3 lata temu

Ostatnio: 4 godziny temu

2

Vavr własnie chciałem ominąć. Chciałem wiedzieć jak sobie dobrze z tym poradzić bez tej biblioteki. Nie zawsze można jej użyć a i dawniej jej nie było, więc trzeba było bez tego dobrze kodzić.

Javy8 tez kiedys nie bylo. Najlepiej utknac w czasach javy1 nie? Bo dawnie nie bylo ;)

Aż mi się przypomniało jak kiedys zasugerowałem użycie Either i odpowiedź była "że to nie Scala". Niestety trafiają się takie ameby umysłowe które potrafią zakazać dobrych rozwiązan... - scibi92 2019-08-29 10:00

Pozostało 580 znaków

2019-08-29 10:51

Rejestracja: 4 lata temu

Ostatnio: 1 godzina temu

Lokalizacja: U krasnoludów - pod górą

4

W tym przypadku rozwiązanie to byłoby dokładnie UserResponse (można jak klasę bazową/interfejs z dwoma implementacjami OKResponse i ErrorResponse).
Tylko jak będzie miał więcej takich metod (jak addUser) to sie trochę napiszesz... Więc pewnie zrobisz to generycznie (OKResponse<t> { private T response; }... I w końcu wyjdzie, że zrobiłeś właśnie swojego EIthera, tylko gorszego.

Co do wyjątków - są dla ludzi, ale generalnie warto jednak używać tylko na sytuacje ostateczne - u Ciebie akurat własnie wyjątek, to żaden wyjątek (żadna panika) i raczej warto Eitherem pojechać. Dlaczego: Wyjatki się gorzej komponują, rzuconego wyjątku nie podstawisz pod zmienną (w intuicyjny sposób -wyjątek złapany w zmiennną przestaje być dalej propagowany ).
Gdyby to był Spring kontroller - i wyniku/wyjątku już bym w swoim kodzie nie łapał (bo byłby tylko przez spring obsługiwany i pchany na HTTP) to wyjatek nie byłby taki zły.

Co do VAVR nawet jeśli by tam Eithera (i Optiona) nie było to polecam ze względu na niemutowalne kolekcje. Jeżeli robisz typowy soft biznesowy to kolekcje z VAVR nie tylko są przyjemniejsze w użyciu (niż ta zabawa w stream(), collect()), są przede wszystkim bezpieczniejsze (mniej błędogęnne). Do tego w realistycznych przypadkach często wydajniesjsze(!!!), bo nie musisz stosować defensywnego kopiowania. To ostatnie dyskusyjne - mało kto stosuje defensywne kopiowanie (ale mi się czesto kiedyś zdarzało. wiec po przejsciu na VAVR moje procki odetchnęly). jakkolwiek w typowym biznesowym sofcie i tak wydajnoć kolekcji praktycznie nie ma znaczenia (jak często obrabiasz kolekcje większe niż 500 elementów?).

Jak zobaczysz jak Ci spada ilośc głupich błędów w logice to nie będziesz na java.util. chciał patrzeć (szczególnie w projektach zespołowych).


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 8x, ostatnio: jarekr000000, 2019-08-29 11:00

Pozostało 580 znaków

2019-08-29 11:40

Rejestracja: 5 lat temu

Ostatnio: 4 godziny temu

Lokalizacja: Warszawa

1

A tak swoją drogą jestem na 80% pewien że wprowadzą Either do JDK w przyszłości. Wprowadzily lambdy, streamy, teraz wprowadzaja pattern matching, only a matter of (long) time


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
pytanie czy wprowadza tak ja vavr, gdzie listy, optiony, eithery, try itp są ze sobą całkowicie kompatybilne - danek 2019-08-29 11:55

Pozostało 580 znaków

Odpowiedz

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0