Jeśli język z natury obsługuje wyjątki, preferowane jest zgłaszanie wyjątków, a klienci mogą wychwycić wyjątek, jeśli nie chcą, aby spowodował błąd. W rzeczywistości klienci Twojego kodu oczekują wyjątków i napotkają wiele błędów, ponieważ nie będą sprawdzać zwracanych wartości.
Istnieje kilka zalet korzystania z wyjątków, jeśli masz wybór.
Wiadomości
Wyjątki zawierają czytelne dla użytkownika komunikaty o błędach, które mogą być wykorzystane przez programistów do debugowania, a nawet wyświetlane użytkownikom w razie potrzeby. Jeśli konsumujący kod nie jest w stanie obsłużyć wyjątku, zawsze może go zarejestrować, aby programiści mogli przejrzeć dzienniki bez konieczności zatrzymywania się przy każdym innym śledzeniu, aby dowiedzieć się, jaka była wartość zwracana i zmapować ją w tabeli, aby dowiedzieć się, co to jest faktyczny wyjątek.
W przypadku wartości zwracanych nie można łatwo podać dodatkowych informacji. Niektóre języki obsługują wykonywanie wywołań metod w celu otrzymania ostatniego komunikatu o błędzie, więc problem ten został nieco rozwiązany, ale wymaga to od dzwoniącego wykonania dodatkowych wywołań, a czasami wymaga dostępu do „specjalnego obiektu”, który przenosi te informacje.
W przypadku komunikatów o wyjątkach podaję jak najwięcej kontekstów, takich jak:
Nie można pobrać zasady o nazwie „foo” dla „paska” użytkownika, do którego odwołano się w profilu użytkownika.
Porównaj to z kodem zwrotnym -85. Który wolisz?
Stosy połączeń
Wyjątki zwykle zawierają również szczegółowe stosy wywołań, które pomagają debugować kod szybciej i szybciej, a także mogą być rejestrowane przez kod wywołujący, jeśli jest to pożądane. Dzięki temu programiści mogą precyzyjnie wskazać problem na dokładną linię, a zatem są bardzo wydajne. Jeszcze raz porównaj to do pliku dziennika ze zwracanymi wartościami (np. -85, 101, 0 itd.). Który wolisz?
Podejście szybko tendencyjne
Jeśli metoda zostanie wywołana w miejscu, które się nie powiedzie, wygeneruje wyjątek. Kod wywołujący musi albo wyraźnie wyłączyć wyjątek, albo zawiedzie. Przekonałem się, że jest to naprawdę niesamowite, ponieważ podczas programowania i testowania (a nawet w produkcji) kod szybko zawodzi, co zmusza programistów do jego naprawy. W przypadku wartości zwracanych, jeśli brakuje sprawdzania wartości zwracanej, błąd jest cicho ignorowany, a błąd pojawia się gdzieś nieoczekiwanie, zwykle z dużo wyższym kosztem debugowania i naprawy.
Wyjątki dotyczące zawijania i rozpakowywania
Wyjątki mogą być zawinięte w inne wyjątki, a następnie rozpakowane w razie potrzeby. Na przykład Twój kod może wyrzucić, ArgumentNullException
który kod wywołujący może zawinąć do wewnątrz, UnableToRetrievePolicyException
ponieważ operacja nie powiodła się w kodzie wywołującym. Podczas gdy użytkownikowi może zostać wyświetlony komunikat podobny do powyższego przykładu, niektóre kody diagnostyczne mogą rozpakować wyjątek i stwierdzić, że to ArgumentNullException
on spowodował problem, co oznacza, że jest to błąd kodowania w kodzie klienta. Może to następnie uruchomić alert, aby programista mógł naprawić kod. Takie zaawansowane scenariusze nie są łatwe do wdrożenia z wartościami zwracanymi.
Prostota kodu
Ten jest nieco trudniejszy do wyjaśnienia, ale nauczyłem się dzięki temu kodowaniu zarówno z wartościami zwracanymi, jak i wyjątkami. Kod, który został napisany przy użyciu wartości zwracanych, zwykle wykonuje wywołanie, a następnie przeprowadza serię kontroli wartości zwracanej. W niektórych przypadkach wywołałoby inną metodę, a teraz będzie miała kolejną serię kontroli zwracanych wartości z tej metody. Z wyjątkami obsługa wyjątków jest znacznie prostsza w większości, jeśli nie we wszystkich przypadkach. Masz bloki try / catch / wreszcie, a środowisko wykonawcze stara się wykonać kod w blokach ostatecznie w celu wyczyszczenia. Nawet zagnieżdżone bloki try / catch / wreszcie są stosunkowo łatwiejsze do przejścia i utrzymania niż zagnieżdżone if / else i powiązane wartości zwracane z wielu metod.
Wniosek
Jeśli platforma, z której korzystasz, obsługuje wyjątki (zwłaszcza takie jak Java lub .NET), to zdecydowanie powinieneś założyć, że nie ma innego wyjścia, niż zgłaszanie wyjątków, ponieważ platformy te mają wytyczne do zgłaszania wyjątków, a Twoi klienci będą oczekiwać więc. Gdybym korzystał z twojej biblioteki, nie zawracam sobie głowy sprawdzaniem zwracanych wartości, ponieważ spodziewam się wyjątków, tak wygląda świat na tych platformach.
Gdyby jednak był to C ++, ustalenie tego byłoby nieco trudniejsze, ponieważ istnieje duża baza kodów z kodami zwrotnymi, a duża liczba programistów jest dostosowywana do zwracania wartości w przeciwieństwie do wyjątków (np. Windows jest bogaty w HRESULT) . Co więcej, w wielu aplikacjach może to być również problem z wydajnością (lub przynajmniej postrzegany jako taki).
try
/catch
istnieje. Dodatkowo możesz umieścić swójtry
/catch
dużo dalej w stosie w bardziej odpowiednim miejscu do obsługi go (pozwalając na większe rozdzielenie obaw).