Wyjątki czy instrukcje warunkowe ?

0

Mam pytanko. Czy istnieje jakaś reguła dotycząca obsługi błędów ? Czy jeśli coś da się obsłużyć rzucając wyjątkiem to nie kombinować z instrukcjami warunkowymi ? Czy może starać się unikać wyjątków i obsługiwać nimi tylko w ostateczności ? Jest wiele sytuacji w których można obsłużyć i tym i tym więc zastanawiam się co lepsze. Czy to zupełnie bez różnicy ? np

 
if (n < 4) {
System.out.println("Liczba nie może być mniejsza od 4 !");
System.exit(0);
}

lub

if (n < 4) throw new IllegalArgumentException("Liczba nie moze byc mniejsza od 4!");
//.....
// obsługa wyjątku
 

Oprócz tego, że w drugim przykładzie mamy więcej pisania to są jeszcze jakieś różnicę ?

1

Są. Jeśli piszesz bibliotekę z której ktoś ma potem korzystać to lepiej rzucać wyjątkami bo jest to bardziej czytelne i mniej błędogenne. Tak samo jeśli potencjalnych błędów może być wiele. Poza tym wyjątki to są wyjątki -> sytuacje wyjątkowe. W wielu sytuacjach w ogóle nie robiłbyś takiego sprawdzenia czy n<4 bo wiesz że będziesz przekazywał poprawne parametry :) Wyjątek oznacza że "coś poszło nie tak". Nie próbuj używać wyjątków do sterowania przepływem programu.

0

a w takim przykładzie :

public class Account {
 // ...
 private double balance;
 // ... 
 
 public void withdraw(double d) {
    if (d <= 0) throw new IllegalArgumentException("Withdrawal should be > 0");
    if (balance - d < 0)
      throw new IllegalArgumentException("Withdrawal exceeding balance not allowed");
    balance -= d;
  }
 

powinienem zostawić tak jak jest ? to też powiedzmy obsługa programu więc może to obsłużyć ifami ? :P
No i jednocześnie coś poszło nie tak : ktoś chce wyjąć za dużo kasiory niż ma :D

0

A jak zwrócisz informacje użytkownikowi że coś poszło nie tak w takim razie? ;)

0

obsługując wyjątek, np w klauzuli catch w bloku dodam instrukcję : return "Nie możesz wypłacić więcej niż masz" lub od razu po ifie zamiast zgłoszenia wyjątku program wykona instrukcję : System.out.println("Nie możesz wypłacić więcej niż masz") Czyli można to zrobić znowu na 2 sposoby, według mnie wyjątek tutaj lepiej odpowiada, prawda ?

0

Zdajesz sobie sprawę z tego że nie możesz sobie ot tak z d**y zwracać stringów? Szczególnie kiedy błędów może być dużo? Jak to potem chcesz pokazać użytkownikowi? Wyjątki maja ten plus że są typesafe. Możesz je obsługiwać na podstawie ich typu. String z wiadomością jest mało użyteczny. A co jak aplikacja ma wiele wersji jezykowych? A co jeśli metoda ma zwrócic coś sensownego, jakis obiekt i nie możesz sobie ot tak zwrócić stringa? ;]
A system out to w ogole idiotyczny pomysł. Wyobraź sobie że ktoś używa tego w aplikacji webowej. Gdzie on niby tego system outa ma zobaczyć? o_O Albo w aplikacji z jakimś GUI?

edit: wyjątki dodatkowo łatwo przechodzą "dalej". Wyobraź sobie jak skomplikowana byłaby obsluga błędów kiedy różne rodzaje błędów chciałbyś obsługiwać na pozomie różnych metod (np. metoda1 woła metode2 a ta woła metode3, a ty chcesz część błędów obsługiwać w jednej, część w drugiej a część w trzeciej metodzie).
Oczywiście to nie znaczy ze zawsze masz rzucać wyjątki ;) Jeśli masz rzucic wyjątek który zaraz sam złapiesz to może to nie mieć wielkiego sensu. Poza tym zwykle wyjątki rzuca się głównie z metod z publicznego API.

0

Załóżmy ze metoda zwraca Stringa i że program działa jako aplikacja konsolowa. Na moim poziomie nauki (podstawowy jak widać) nie miałem styczności z GUI ani z aplikacjami webowymi więc wolałbym się nie rozwodzić nad słusznością tego kodu a raczej nad jego poprawnością. A poprawny jak widać jest, bo się kompiluje i działa tak jak powinien. Więc pytanie nadal to samo. Którym sposobem byłoby lepiej to zrobić i dlaczego ? Jeśli ma to w tym przypadku jakieś znaczenie w ogóle

1

A poprawny jak widać jest, bo się kompiluje i działa tak jak powinien

Kod ma być elegancki, uniwersalny i latwo rozszerzalny. Wtedy jest dobry i poprawny. To że się kompiluje albo że daje oczekiwanie wyniki to jest zupełnie nieistotna kwestia. Dobrze napisany kod można łatwo poprawić tak żeby się kompilował i dawał dobre wyniki. Źle napisany kod przy próbie modyfikacji okazuje się zwykle bezużyteczny i leci do kosza.

Ale odpowiedź brzmi: zwracanie wartości która określa "błąd' jest złym podejściem. Bo przecież z tym stringiem też cos potem byś chciał robić. Więc musisz napisać po powrocie z takiej funkcji drabinkę ifów która sprawdzi czy dostałeś poprawny wynik czy stringa z błędem. W C nie ma wyjątków i masz masę funkcji które w razie błędu zwracają pewną określoną wartość (np. jakieś -1) i ustawiają typ błędu za pomocą magicznej zmiennej globalnej. Obsługa takich błędów to męka.

1

Programiści mają różne zdania co do czytelności wyjątków. Przykładowo tekst Joel'a Spolskyego: http://www.joelonsoftware.com/items/2003/10/13.html

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