Obecnie próbuję ulepszyć sposób korzystania z wyjątków i znalazłem ważne rozróżnienie między wyjątkami, które oznaczają błędy programowania (np. Ktoś przekazał wartość NULL jako argument lub wywołał metodę na obiekcie po jego usunięciu), a tymi, które oznaczają błąd w operacja, która nie jest błędem osoby dzwoniącej (np. wyjątek We / Wy).
Jak te dwa wyjątki należy traktować inaczej? Czy uważasz, że wyjątki od błędów muszą być wyraźnie udokumentowane, czy wystarczy, aby udokumentować odpowiednie warunki wstępne? Czy możesz pominąć dokumentację warunku wstępnego lub wyjątku dotyczącego błędu, jeśli powinno to być oczywiste (na przykład ObjectDisposedException
podczas wywoływania metody na usuwanym obiekcie)
java
c#
c++
exceptions
Medo42
źródło
źródło
Odpowiedzi:
Myślę, że jesteś na dobrej drodze. Ani rzucanie, łapanie, ani dokumentowanie wszystkich potencjalnie możliwych do rzucenia wyjątków nie ma większego sensu. Są chwile, w których rygorystyczność produktu wymaga wyższego stopnia wyjątkowego zatrudnienia i dokumentacji (np. Pewne aspekty krytyczne dla bezpieczeństwa systemów).
Strategia polegająca na bardziej defensywnym wykorzystaniu koncepcji kontraktowych do identyfikowania warunków wstępnych (i dodatkowych) na szczególnie dzwoniących w dalszej kolejności (np. Wszystko, co przypomina członka publicznego lub chronionego) będzie często bardziej skuteczna i elastyczna. Dotyczy to nie tylko wdrożenia, ale także dokumentacji. Jeśli programiści wiedzą, czego się spodziewają, są bardziej skłonni do przestrzegania reguł i rzadziej mogą się pomylić lub niewłaściwie wykorzystać napisany kod.
Niektóre z typowych rzeczy, które powinny być udokumentowane, obejmują przypadek parametrów zerowych. Często wiąże się to z konsekwencją ich zastosowania, która prowadzi do czegoś, czego normalnie nie można się spodziewać, ale jest dozwolona i używana z różnych powodów, czasem ze względu na elastyczność. Jako konsument członka, który ma parametry, które pozwalają na wartość zerową lub inne specjalne, nieracjonalne wartości (takie jak czas ujemny lub wartości ujemne), spodziewam się, że zostaną zidentyfikowane i wyjaśnione.
W przypadku parametrów innych niż null, jako konsument członka publicznego lub chronionego, chcę wiedzieć, że wartość null jest niedozwolona. Chcę wiedzieć, jaki jest prawidłowy zakres wartości w danym kontekście. Chcę poznać konsekwencje używania wartości, które są poza normalnym zakresem, ale poza tym są poprawne w innym kontekście wywoływania (np. Wartość typu jest ogólnie poprawna dla dowolnej operacji, ale nie tutaj - jak parametr boolowski, który nie nie należy oczekiwać wartości false jako prawidłowej wartości.
Jeśli chodzi o platformę lub inne dobrze znane interfejsy, nie sądzę, abyś musiał się starać w dokumentowaniu. Ponieważ jednak jako programista masz możliwość różnicowania implementacji w zależności od wskazówek platformy, należy pamiętać o tym, w jaki sposób wskazówki te mogą być wartościowe.
Specyficzne dla IDisposable, często implementacje tego interfejsu oferują alternatywną metodę, która jest lepsza niż proces jawnego usuwania. W takich przypadkach zaznacz preferowaną metodę i zauważ, że wyraźne usuwanie nie jest preferowane.
źródło
performReadCommand(ICommand cmd, int replySizeBytes)
- czy spodziewałbyś się, że wartość null byłaby akceptowalna dla cmd lub wartość ujemna dla replySizeBytes? Dokumentacja IMO byłaby konieczna tylko wtedy, gdyby te wartości były rzeczywiście dozwolone, i prawdopodobnie powinieneś się zastanowić, czy 0 jest ważne dla replySizeBytes.Oto moje własne myśli. Zauważ, że nie jestem zbyt pewien, że jest to najlepsza droga, dlatego właśnie to pytanie stworzyłem.
O ile rozumiem, nie ma sensu, aby natychmiastowy rozmówca obsługiwał wyjątki dotyczące błędów programistycznych, powinien zamiast tego zapewnić spełnienie warunków wstępnych. Tylko „zewnętrzne” procedury obsługi wyjątków na granicach zadań powinny je wychwycić, aby mogły utrzymać działanie systemu w przypadku niepowodzenia zadania.
Aby mieć pewność, że kod klienta będzie w stanie przechwycić wyjątki „awarii” bez przypadkowego wychwycenia wyjątków błędów, tworzę teraz własne klasy wyjątków dla wszystkich wyjątków błędów i dokumentuję je metodami, które je wyrzucają. Zmusiłbym ich do sprawdzania wyjątków w Javie.
Do niedawna próbowałem udokumentować wszystkie wyjątki, które może wywołać metoda, ale czasami tworzy nieporadną listę, którą należy udokumentować w każdej metodzie w łańcuchu wywołań, dopóki nie pokażesz, że błąd się nie zdarzy. Zamiast tego dokumentuję teraz warunki wstępne w opisach podsumowania / parametrów i nawet nie wspominam, co się stanie, jeśli nie zostaną spełnione. Chodzi o to, że ludzie nie powinni i tak wyraźnie wychwytywać tych wyjątków, więc nie ma potrzeby dokumentowania ich typów.
Aby udokumentować warunki wstępne, stwierdzenie tego, co oczywiste, po prostu tworzy niepotrzebny bałagan - jeśli przekazanie wartości null do metody nie ma oczywistego sensu, osoba dzwoniąca musi oczekiwać wyjątku, jeśli i tak przejdzie null, nawet jeśli nie jest to udokumentowane. To samo dotyczy przypadku ObjectDisposedException - ten interfejs jest tak szeroko używany, że ktoś dzwoniący Dispose byłby świadomy odpowiedzialności za zapewnienie, że nikt nie będzie kontynuował używania obiektu.
źródło
Rozsądna zasada:
Możesz chcieć mieć najwyższej klasy moduł obsługi wyjątków, który przechwytuje wszystko, czego nie da się obsłużyć poniżej, aby nie dopuścić do upadku aplikacji, ale będzie to silnie zależeć od konkretnej aplikacji. Na przykład aplikacje iOS wolą wychwytywać jak najwięcej; aplikacja wiersza poleceń może być całkowicie OK, jeśli nie wychwytuje prawie żadnych wyjątków.
źródło
Nawet Java nie „dokumentuje” wszystkich wyjątków. Pomimo wymogu, aby każdy klauzula
throw
była wymieniona wthrows
klauzuli, każdy wiersz kodu może wygenerować znak „a”RuntimeException
bez potrzeby deklarowania go w podpisie metody.źródło
Standardowym sposobem na to jest podejście Java. Błędy programowania powinny być odznaczonymi wyjątkami i nie powinny być wychwytywane, aby zapewnić szybką awarię. Błędy umowy są sprawdzane w wyjątkach i powinny być odpowiednio obsługiwane przez klienta.
źródło