Nie zgadzam się z bardziej doświadczonym programistą w tej sprawie i zastanawiam się, co sądzą o tym inni; nasze środowisko to Java, EJB 3, usługi itp.
Kod, który napisałem, wywołuje usługę w celu zdobywania rzeczy i tworzenia rzeczy. Problem, na który natrafiłem, polegał na tym, że otrzymałem wyjątki zerowego wskaźnika, które nie miały sensu. Na przykład, kiedy poproszę usługę o utworzenie obiektu, otrzymuję wartość zerową; gdy próbuję wyszukać obiekt o znanym ważnym identyfikatorze, zwracam wartość null. Spędziłem trochę czasu próbując dowiedzieć się, co było nie tak w moim kodzie; ponieważ jestem mniej doświadczony, zwykle zakładam, że zrobiłem coś złego, ale okazuje się, że przyczyną zerowych zwrotów było bezpieczeństwo. Jeśli użytkownik główny korzystający z mojej usługi nie miał odpowiednich uprawnień do usługi docelowej, wówczas po prostu zwraca wartość null. Większość innych usług tutaj również nie jest dobrze udokumentowana, więc najwyraźniej jest to po prostu coś, co musisz wiedzieć.
Jest to dość mylące, ponieważ programista pisze kod, który wchodzi w interakcję z usługą. Byłoby dla mnie o wiele bardziej sensowne, gdyby usługa stanowiła wyjątek, który powiedziałby mi, że użytkownik nie ma odpowiednich uprawnień do załadowania lub utworzenia tej rzeczy; Od razu wiedziałbym, dlaczego moja usługa nie działa zgodnie z oczekiwaniami.
Bardziej doświadczony programista, który napisał usługę, argumentował, że żądanie danych nie jest warunkiem błędu, a wyjątki powinny być zgłaszane tylko w przypadku błędu, a nie wtedy, gdy użytkownik nie ma dostępu do danych. Dane te są często sprawdzane w interfejsie GUI, a dla tych użytkowników bez odpowiednich uprawnień, te rzeczy po prostu „nie istnieją”. Krótko mówiąc: pytanie nie jest złe, stąd nie ma wyjątku. Metody Get zwracają wartość null, ponieważ dla tych użytkowników rzeczy „nie istnieją”. Metody tworzenia zwracają wartość null, gdy użytkownik nie mógł utworzyć tej rzeczy.
Czy to jest normalna i / lub dobra praktyka? Wolę używać wyjątków, ponieważ znacznie łatwiej jest mi wiedzieć, co się dzieje. Wolałbym więc na przykład zgłosić wyjątek NotFoundException, jeśli poprosiłeś o obiekt z niepoprawnym identyfikatorem, zamiast zwracać wartość null.
źródło
Odpowiedzi:
Pytanie o coś może nie być błędem, ale brak uprawnień do czegoś, o co prosiłeś, to z pewnością jakiś błąd. Wyjątki to alternatywny sposób zgłaszania wyjątkowych warunków, który można zastosować zamiast specjalnych wartości zwracanych (takich jak
null
, jak napisałeś, absolutnie nie pomoże, jeśli istnieje> 1 możliwy powód, dla którego wszystko może pójść nie tak (nawet jeśli dokładnie 1 możliwy powód, w następnej wersji mogą istnieć 2 możliwe powody, więc użycienull
jako wartości zwracanej wskazującej na niepowodzenie oznaczałoby malowanie się w rogu). Jeśli usługa nie zgłosi w żaden sposób, dlaczego nie zrobi tego, o co prosiłeś, to zdecydowanie jest to zły projekt.Niezależnie od tego, czy użyć specjalnej wartości zwracanej (np. Ujemne liczby całkowite są przydatne dla funkcji, które zwykle zwracają nieujemną liczbę całkowitą), wyjątek, globalny moduł obsługi błędów lub program rejestrujący itp. Jest szczegółem implementacji na końcu. Wybór zależy od języka, sytuacji, konwencji i jest również kwestią gustu. Najważniejsze jest to, że powinien istnieć jakiś bezpośredni sposób ustalenia, dlaczego coś nie działa. W przeciwnym razie twoją jedyną opcją jest wyrzucanie śmieci z różnymi opcjami i cokolwiek, aby dowiedzieć się, co koreluje z zachowaniem czarnej skrzynki, i to strata czasu.
String.substring()
zgłasza i,IndexOutOfBoundsException
jeśli indeks jest poza zakresem. Nie mogę wymyślić żadnych korzyści z powrotunull
, chociaż - filozoficznie - można argumentować, że aString
nie zawiera niczego poza swoimi granicami, więcnull
byłaby to logiczna wartość zwracana. Bycie logiczno-filozoficznym i praktycznym to oczywiście dwa różne zwierzęta.źródło
substring
do zwrócenia odwołania zerowego. IMHO powinny być dwie oddzielne funkcje - jedna z nich obiecuje albo zwrócić żądaną liczbę znaków, albo zgłosić wyjątek, a jedna zwraca tyle, ile może. Każda metoda byłaby znacznie lepsza od drugiej w niektórych kontekstach.Wszystko sprowadza się do umowy. Jeśli umowa mówi, że możesz zażądać czegoś, co nie istnieje, powinno zawierać informację o tym, co się stanie (obiekt zerowy lub zerowy).
Z drugiej strony, jeśli umowa mówi, że powinieneś najpierw wywołać inną metodę (
DoesSomethingExist()
), a następnie wywołać tęGet
metodę, wówczas umowa może powiedzieć, że możesz uzyskać tylko rzeczy, które istnieją, i jeśli nie, wyrzucić wyjątek. Komunikat wyjątku może brzmieć „DoesSomethingExist()
Najpierw zadzwoń ”, co jest przydatnym komunikatem o błędzie.źródło
findAllThings
metoda, powiedziałbym, że właściwe jest zwrócenie pustej listy lub podzbioru, jeśli są pewne lub wszystkie rzeczy, których nie wolno ci widzieć. W ten sam sposób mogę na blogu wyświetlać tylko posty do edycji należące do bieżącego użytkownika. Ale jeśli ten użytkownik następnie spróbuje zmodyfikować adres URL i edytować inny post ...Nie ma jednej, uniwersalnej odpowiedzi na wszystkie pytania. To, czy użyć wyjątków, czy zwrócić null, zależy od sytuacji.
Zamiast patrzeć na to wyłącznie z dogmatycznego punktu widzenia, spójrz na interfejs jako interfejs użytkownika . Interfejsy użytkownika powinny być użyteczne . Niezależnie od własnych opinii na temat „właściwego” sposobu zrobienia czegoś, wybierz metodę, która jest najbardziej użyteczna z perspektywy osoby korzystającej z Twojego interfejsu.
Jeśli osoba dzwoniąca musi wiedzieć, dlaczego obiekt nie jest zwracany, odpowiedni jest wyjątek. Jeśli jednak ogólna koncepcja brzmi „jeśli nie masz pozwolenia, nie istnieje”, wartość null jest akceptowalna.
Szczególnie w twoim przypadku powiedziałbym, że wartości zerowe są całkowicie akceptowalne do wyszukiwania elementu, jeśli osoba dzwoniąca musi najpierw zalogować się lub połączyć z serwerem. Wtedy powiedziano ci, że masz lub nie masz pozwolenia. Gdy miniesz bramę, uzasadnione jest, że kiedy szukasz czegoś, do czego nie masz pozwolenia (a nawet wiesz, że istnieje), powinieneś otrzymać zero.
Z drugiej strony, jeśli nie masz początkowego połączenia lub kroku logowania, wyjątek ma sens. Jeśli dzwoniący wie, że element istnieje i nie odzyskuje go, interfejs API nie jest pomocny w zwróceniu wartości null.
Jednak tworzenie przedmiotu to inna historia. Prawdopodobnie może być wiele przyczyn niepowodzenia - brak uprawnień, złe parametry, brak pamięci w serwerze itp. Jeśli programista otrzyma wartość null dla wszystkich tych warunków, nie będzie w stanie określić właściwego sposobu działania .
Aby odpowiedzieć na pytanie, zadaj sobie pytanie, jakie jest najbardziej przydatne rozwiązanie z perspektywy osoby korzystającej z usługi. Może się okazać, że droga ty używasz go jest nietypowy, a najczęstszym przypadku zerowy jest prawidłowa odpowiedź.
Więc nie wdawaj się w wojnę religijną, zdecyduj, co jest właściwe dla tego konkretnego problemu.
źródło
Zdecydowanie uważam, że to zły projekt . Wskaźnik zerowy nie jest dla mnie prawidłową odpowiedzią i może być trudny w zarządzaniu.
Jeśli użytkownik spróbuje połączyć usługę bez odpowiedniego poświadczenia, powinienem odpowiedzieć jasną i zwięzłą odpowiedzią. Odpowiedzią może być wyjątek lub obiekt specjalny, ale nie zero.
Powinieneś pozostawić zerową odpowiedź, gdy połączenie sieciowe zostanie zerwane lub inna nieoczekiwana krytyczna usterka.
Co więcej, czas spędzony na zrozumieniu, dlaczego masz wartość zerową, jest silnym argumentem. Każdy fragment kodu powinien być łatwy do zrozumienia i użycia. Posiadanie wartości zerowej nie jest prawdą.
źródło
Mając na uwadze dobre projektowanie oprogramowania, powinieneś pomyśleć o życiu swojego projektu.
Zwracając
null
, jak powiedziano, nie podajesz żadnych informacji klientowi. Spójrz, co ci się przydarzyło, na początku nie zdawałeś sobie sprawy, gdzie jest problem. Co więcej, jeśli nie podano żadnej dokumentacji, jest to bałagan.Zgłaszając wyjątek, możesz stwierdzić, co poszło nie tak. Możesz nawet dostosować wyświetlany tekst, aby był bardziej szczegółowy, jeśli chcesz.
Z drugiej strony, zwracając
null
, sprawisz , że klient zbada, co się dzieje.Ponadto zdałeś sobie sprawę, że był problem, ponieważ dostałeś się gdzie indziej
NullPointerException
. Teraz wyobraź sobie, że nie przechowujesz zwrotu tej funkcji ... Będziesz zmuszony otoczyć każde wywołanie tej funkcjiif else
blokiem ...Z mojego punktu widzenia powrót
null
to zła praktyka.źródło
Z mojego punktu widzenia nie ma to sensu.
Zapytanie o dane bez pozwolenia powinno spowodować wyjątek, ponieważ jest to nieoczekiwany wynik - brak rezultatu - bez odpowiedniego dostępu.
Analogia : kod odpowiedzi dla
GET
autoryzacji200 ok
bez danych nie jest bez danych, tak naprawdę jest401 Unauthorized
.źródło
Zwracanie wartości null nie jest świetne. Nic ci nie mówi. Na przykład, jeśli aplikacja próbuje coś wyszukać, a odpowiedź na oba problemy bezpieczeństwa jest zerowa, a jeśli element nie istnieje, to jak odróżnić te dwa elementy?
Znacząca odpowiedź może pozwolić aplikacji na dokonywanie logicznych wyborów dotyczących tego, co robić dalej lub jak rozwiązywać problemy.
źródło
Jeśli główną przyczyną jest nieuwierzytelniony użytkownik, wolę twardą odpowiedź HTTP 401, być może z przekierowaniem na ładną stronę z wiadomością (i powiadomieniem dla kogoś, kogo to obchodzi). Przyczyny związane z autoryzacją są bardziej indywidualne; istnieją argumenty za zwracaniem błędów HTTP (powiedzmy 403) i argumenty za zwracaniem specjalnych poprawnie sformułowanych kodów / komunikatów w odpowiedzi usługi.
Wyjątki należy stosować tylko w wyjątkowych okolicznościach i oznaczać, że coś poszło nie tak. Nie zgadzam się, że powinny być przeciążone, co oznacza „niedozwolone”. (To samo dotyczy zerowej wartości zwracanej: Nie zgadzam się, że należy ją stosować w znaczeniu „niedozwolony”).
źródło
Aby zagrać w adwokata diabłów, postaram się powrócić do zera.
Moim zdaniem jest tylko jedna sytuacja, w której tego rodzaju reakcja jest prawie do zaakceptowania, i tak jak w tym przypadku, gdy chodzi o bezpieczeństwo.
Bardzo łatwo jest przypadkowo podać szczegóły systemu, o których osoby nieupoważnione nie powinny wiedzieć. Tego należy unikać.
Weźmy na przykład sprawdzanie nazwy użytkownika i hasła. Zwrócenie błędu „Nie znaleziono nazwy użytkownika” i błędu „Nieprawidłowe hasło” jako oddzielnych kodów błędów oczywiście otworzyłoby cię na poważne problemy bezpieczeństwa, ponieważ ktoś mógłby najpierw poszukać prawidłowej nazwy użytkownika, a następnie hasła. Lepszym rozwiązaniem byłoby zwrócenie ogólnego „Nieprawidłowa nazwa użytkownika / hasło”.
Tak więc w tym konkretnym przypadku powiedziałbym, że powrót jest prawie w porządku,
null
ale zgadzam się, że bardzo nieprzyjemnie byłoby z nim pracować.źródło
null
jest dokładnie najmniej pomocną odpowiedzią. Prawie wszystko inne mogłoby potencjalnie zostać wykorzystane do odkrycia czegoś o systemie. Powód narzekał OP, ponieważnull
zwrot nie tylko nie wyjaśnił, że był nawet nieprzydatny. Taki jest celowy cel ... powiedzenie absolutnie nic i bycie niepomocnym. Misja zrealizowana moim zdaniem.Myślę, że return null jest nieprzyjazny, kiedy klient wywołuje tę metodę i zwraca null, klient nie wie, co się stało i dlaczego zwrócił null. Powinniśmy więc wykonać wykonanie sensowne i dostarczyć dokumentację opisującą wykonanie.
źródło