Myślę, że wszystkie odpowiedzi, które wyjaśniają, że nie powinieneś mieć flagi kontrolującej, czy wyjątek jest zgłaszany, czy nie są dobre. Ich rada byłaby moją radą dla każdego, kto odczuwa potrzebę zadania tego pytania.
Chciałem jednak zaznaczyć, że istnieje znaczący wyjątek od tej zasady. Gdy jesteś wystarczająco zaawansowany, aby rozpocząć tworzenie interfejsów API, które będą używane przez setki innych osób, są przypadki, w których możesz chcieć podać taką flagę. Kiedy piszesz API, nie piszesz tylko dla purystów. Piszesz do prawdziwych klientów, którzy mają prawdziwe pragnienia. Częścią twojego zadania jest uszczęśliwienie ich interfejsem API. Staje się to problemem społecznym, a nie programowym, a czasem problemy społeczne dyktują rozwiązania, które byłyby mniej niż idealne jako samodzielne rozwiązania programistyczne.
Może się okazać, że masz dwóch różnych użytkowników interfejsu API, z których jeden chce wyjątków, a drugi nie. Przykładem, w którym może się to zdarzyć, jest biblioteka używana zarówno w programowaniu, jak i systemie wbudowanym. W środowiskach programistycznych użytkownicy prawdopodobnie będą chcieli mieć wyjątki wszędzie. Wyjątki są bardzo popularne w przypadku nieoczekiwanych sytuacji. Są one jednak zabronione w wielu osadzonych sytuacjach, ponieważ są zbyt trudne do przeanalizowania ograniczeń w czasie rzeczywistym. Kiedy zależy ci nie tylko na średnim czasie wykonywania funkcji, ale także na czasie pojedynczej zabawy, pomysł odwrócenia stosu w dowolnym dowolnym miejscu jest bardzo niepożądany.
Przykład z życia: biblioteka matematyczna. Jeśli twoja biblioteka matematyczna ma Vector
klasę, która obsługuje uzyskanie wektora jednostki w tym samym kierunku, musisz być w stanie podzielić przez wielkość. Jeśli wartość wynosi 0, masz sytuację dzielenia przez zero. W rozwoju chcesz je złapać . Naprawdę nie chcesz zaskakującego podziału przez kręcenie się 0. Zgłoszenie wyjątku jest bardzo popularnym rozwiązaniem tego problemu. To prawie nigdy się nie zdarza (jest to naprawdę wyjątkowe zachowanie), ale kiedy to się dzieje, chcesz to wiedzieć.
Na platformie wbudowanej nie chcesz tych wyjątków. Bardziej sensowne byłoby sprawdzenieif (this->mag() == 0) return Vector(0, 0, 0);
. W rzeczywistości widzę to w prawdziwym kodzie.
Teraz pomyśl z perspektywy biznesu. Możesz spróbować nauczyć dwóch różnych sposobów korzystania z interfejsu API:
// Development version - exceptions // Embeded version - return 0s
Vector right = forward.cross(up); Vector right = forward.cross(up);
Vector localUp = right.cross(forward); Vector localUp = right.cross(forward);
Vector forwardHat = forward.unit(); Vector forwardHat = forward.tryUnit();
Vector rightHat = right.unit(); Vector rightHat = right.tryUnit();
Vector localUpHat = localUp.unit() Vector localUpHat = localUp.tryUnit();
Jest to zgodne z opiniami większości odpowiedzi tutaj, ale z punktu widzenia firmy jest to niepożądane. Wbudowani programiści będą musieli nauczyć się jednego stylu kodowania, a programiści będą musieli nauczyć się innego. Może to być dość nieznośne i zmusza ludzi do jednego sposobu myślenia. Potencjalnie gorzej: jak udowadniasz, że wersja osadzona nie zawiera kodu zgłaszającego wyjątek? Wersja do rzucania może łatwo wtapiać się, ukrywając się gdzieś w kodzie, dopóki nie znajdzie go droga tablica oceny awarii.
Z drugiej strony, jeśli masz flagę, która włącza lub wyłącza obsługę wyjątków, obie grupy mogą nauczyć się dokładnie tego samego stylu kodowania. W rzeczywistości w wielu przypadkach możesz nawet użyć kodu jednej grupy w projektach drugiej grupy. W przypadku użycia tego kodu unit()
, jeśli faktycznie zależy Ci na tym, co dzieje się w przypadku dzielenia przez 0, powinieneś sam napisać test. Tak więc, jeśli przeniesiesz go do systemu osadzonego, w którym po prostu uzyskasz złe wyniki, takie zachowanie będzie „rozsądne”. Teraz z perspektywy biznesowej raz szkolę programistów, którzy używają tych samych interfejsów API i tych samych stylów we wszystkich obszarach mojej działalności.
W zdecydowanej większości przypadków chcesz postępować zgodnie z radami innych: używaj idiomów podobnych tryGetUnit()
lub podobnych dla funkcji, które nie zgłaszają wyjątków, i zamiast tego zwracaj wartość wartownika, np. Null. Jeśli uważasz, że użytkownicy mogą chcieć korzystać zarówno z obsługi wyjątków, jak i obsługi wyjątków obok siebie w ramach jednego programu, trzymaj się tryGetUnit()
notacji. Istnieje jednak przypadek narożny, w którym rzeczywistość biznesowa może sprawić, że lepiej będzie użyć flagi. Jeśli znajdziesz się w tej narożnej skrzynce, nie bój się podrzucić „zasad” na marginesie. Do tego służą reguły!