Czy to jest antypattern? Czy jest to dopuszczalna praktyka?
try {
//do something
} catch (Exception e) {
try {
//do something in the same line, but being less ambitious
} catch (Exception ex) {
try {
//Do the minimum acceptable
} catch (Exception e1) {
//More try catches?
}
}
}
anti-patterns
exception-handling
Pan Smith
źródło
źródło
Odpowiedzi:
Czasami jest to nieuniknione, szczególnie jeśli kod odzyskiwania może wygenerować wyjątek.
Nie ładnie, ale czasem nie ma alternatywy.
źródło
Nie sądzę, że jest to antypattern, po prostu powszechnie nadużywany.
Większość zagnieżdżonych prób połowu jest rzeczywiście możliwa do uniknięcia i brzydka, do diabła, zwykle jest to produkt młodszych programistów.
Ale są chwile, kiedy nie możesz nic na to poradzić.
Będziesz także potrzebować dodatkowego bool, aby zaznaczyć nieudane wycofanie ...
źródło
Logika jest w porządku - w niektórych sytuacjach może być sensowne wypróbować podejście awaryjne, które samo w sobie może doświadczyć wyjątkowych wydarzeń ... stąd ten wzorzec jest prawie nieunikniony.
Sugeruję jednak, aby poprawić kod:
attemptFallbackMethod
iattemptMinimalRecovery
.finally
blok może mieć więcej sensu - zwykle dzieje się tak w przypadku czegoś, co przypomina „kod czyszczenia zasobów”źródło
W porządku. Refaktoryzacja, którą należy rozważyć, polega na wprowadzeniu kodu do własnej metody i zastosowaniu wczesnych wyjść w celu osiągnięcia sukcesu, umożliwiając pisanie różnych prób zrobienia czegoś na tym samym poziomie:
Kiedy już to rozwiniesz, możesz pomyśleć o podsumowaniu go według strategii.
Następnie skorzystaj z
TrySeveralThingsStrategy
, która jest rodzajem złożonej strategii (dwa wzory w cenie jednego!).Jedno ogromne zastrzeżenie: nie rób tego, chyba że same strategie są wystarczająco złożone lub nie chcesz ich używać w elastyczny sposób. W przeciwnym razie spowalniasz kilka linii prostego kodu z ogromną stertą niepotrzebnej orientacji obiektowej.
źródło
Nie sądzę, że jest to automatycznie anty-wzór, ale unikałbym go, jeśli znajdę łatwiejszy i czystszy sposób na zrobienie tego samego. Jeśli język programowania, w którym pracujesz, ma
finally
konstrukcję, która w niektórych przypadkach może pomóc to wyczyścić.źródło
Nie jest to anty-wzorzec per se, ale wzorzec kodu, który mówi, że trzeba zrefaktoryzować.
I to całkiem proste, wystarczy znać ogólną zasadę, która polega na pisaniu tylko bloku try w tej samej metodzie. Jeśli dobrze wiesz, aby pisać razem pokrewny kod, zwykle wystarczy skopiować i wkleić każdy blok try z jego blokami catch i wkleić go w nowej metodzie, a następnie zastąpić oryginalny blok wywołaniem tej metody.
Ta ogólna zasada oparta jest na sugestii Roberta C. Martina z jego książki „Clean Code”:
Szybki przykład „pseudo-java”. Załóżmy, że mamy coś takiego:
Następnie moglibyśmy refaktoryzować każdą próbę catch iw tym przypadku każdy blok try-catch próbuje tego samego, ale w różnych lokalizacjach (jak wygodne: D), musimy tylko skopiować wklej jeden z bloków try-catch i zastosować metodę .
Teraz używamy tego w tym samym celu, co wcześniej.
Mam nadzieję że to pomogło :)
źródło
Z pewnością zmniejsza to czytelność kodu. Powiedziałbym, że jeśli masz szansę , unikaj zagnieżdżania try-catch.
Jeśli musisz zagnieżdżać try-catch, zawsze zatrzymaj się na minutę i pomyśl:
czy mam szansę je połączyć?
powinienem po prostu wyodrębnić zagnieżdżoną część do nowej metody? Kod będzie znacznie czystszy.
Oczywiste jest, że musisz zagnieździć trzy lub więcej poziomów try-catchów w jednej metodzie, co jest pewnym znakiem czasu dla refaktora.
źródło
Widziałem ten wzorzec w kodzie sieci i ma to sens. Oto podstawowy pomysł w pseudokodzie:
Zasadniczo jest to heurystyka. Jedna nieudana próba połączenia może być po prostu usterką sieci, ale jeśli zdarzy się to dwukrotnie, prawdopodobnie oznacza to, że maszyna, z którą próbujesz się połączyć, jest naprawdę nieosiągalna. Prawdopodobnie istnieją inne sposoby wdrożenia tej koncepcji, ale najprawdopodobniej byłyby jeszcze brzydsze niż próby zagnieżdżenia.
źródło
Rozwiązałem tę sytuację w ten sposób (try-catch with fallback):
źródło
„Musiałem” to zrobić przypadkowo w klasie testowej (JUnit), gdzie metoda setUp () musiała tworzyć obiekty z niepoprawnymi parametrami konstruktora w konstruktorze, który zgłosił wyjątek.
Gdybym musiał na przykład zawieść w budowie 3 niepoprawnych obiektów, potrzebowałbym 3 zagnieżdżonych bloków try-catch. Zamiast tego utworzyłem nową metodę, w której wychwytywano wyjątki, a zwracana wartość była nową instancją klasy, którą testowałem, gdy się powiodła.
Oczywiście potrzebowałem tylko 1 metody, ponieważ zrobiłem to samo 3 razy. Może nie być to dobre rozwiązanie dla zagnieżdżonych bloków, które robią zupełnie inne rzeczy, ale przynajmniej twój kod stałby się bardziej czytelny w większości przypadków.
źródło
Myślę, że to antypattern.
W niektórych przypadkach możesz chcieć wielokrotnych prób, ale tylko jeśli NIE WIESZ, jakiego rodzaju błędu szukasz, np .:
Jeśli nie wiesz, czego szukasz, musisz użyć pierwszego sposobu, który jest IMHO, brzydki i niedziałający. Myślę, że to drugie jest znacznie lepsze.
Jeśli więc wiesz, jakiego rodzaju błędu szukasz, bądź konkretny . W tej samej metodzie nie ma potrzeby zagnieżdżania ani wielokrotnego próbowania.
źródło
W niektórych przypadkach zagnieżdżone Try-Catch jest nieuniknione. Na przykład, gdy sam kod odzyskiwania po błędzie może zgłosić wyjątek. Jednak w celu poprawy czytelności kodu zawsze można wyodrębnić zagnieżdżony blok we własnej metodzie. Sprawdź ten post na blogu, aby uzyskać więcej przykładów zagnieżdżonych bloków Try-Catch-Wreszcie.
źródło
Nigdzie nie ma wzmianki o Anti Pattern w java. Tak, nazywamy kilka rzeczy dobrą i złą praktyką.
Jeśli blok try / catch jest wymagany w bloku catch, to nie możesz mu pomóc. I nie ma alternatywy. Blok blokujący nie może działać jako część próbna, jeśli zostanie zgłoszony wyjątek.
Na przykład :
W powyższym przykładzie metoda zgłasza wyjątek, ale doMethod (używany do obsługi wyjątku metody) nawet zgłasza wyjątek. W takim przypadku musimy użyć try catch w ramach try catch.
sugeruje się, aby tego nie robić ...
źródło