Ich habe eine Methode, die ein Objekt zurückgeben soll, wenn es gefunden wird.
Wenn es nicht gefunden wird, sollte ich:
- return null
- eine Ausnahme auslösen
- andere
exception
error-handling
null
Robert
quelle
quelle
Antworten:
Wenn Sie immer erwarten, einen Wert zu finden, lösen Sie die Ausnahme aus, wenn sie fehlt. Die Ausnahme würde bedeuten, dass es ein Problem gab.
Wenn der Wert fehlen oder vorhanden sein kann und beide für die Anwendungslogik gültig sind, geben Sie eine Null zurück.
Wichtiger: Was machen Sie an anderen Stellen im Code? Konsistenz ist wichtig.
quelle
GetPersonById(25)
würde werfen, wenn diese Person gelöscht wurde,GetPeopleByHairColor("red")
würde aber ein leeres Ergebnis zurückgeben. Ich denke, die Parameter sagen etwas über die Erwartungen aus.Eine Ausnahme nur auslösen, wenn es sich wirklich um einen Fehler handelt. Wenn erwartet wird, dass das Verhalten des Objekts nicht vorhanden ist, geben Sie die Null zurück.
Ansonsten ist es eine Frage der Präferenz.
quelle
Wenn die Methode immer ein Objekt zurückgeben soll, gehen Sie in der Regel mit der Ausnahme vor. Wenn Sie die gelegentliche Null antizipieren und auf bestimmte Weise damit umgehen möchten, wählen Sie die Null.
Was auch immer Sie tun, ich rate dringend von der dritten Option ab: Rückgabe einer Zeichenfolge mit der Aufschrift "WTF".
quelle
Wenn null niemals einen Fehler anzeigt, geben Sie einfach null zurück.
Wenn null immer ein Fehler ist, wird eine Ausnahme ausgelöst.
Wenn null manchmal eine Ausnahme ist, codieren Sie zwei Routinen. Eine Routine löst eine Ausnahme aus und die andere ist eine boolesche Testroutine, die das Objekt in einem Ausgabeparameter zurückgibt, und die Routine gibt eine falsche zurück, wenn das Objekt nicht gefunden wurde.
Es ist schwer, eine Try-Routine zu missbrauchen. Es ist wirklich leicht zu vergessen, nach Null zu suchen.
Wenn also null ein Fehler ist, schreiben Sie einfach
Wenn die Null kein Fehler ist, können Sie so etwas wie codieren
quelle
find
undfindOrFail
von Laravel EloquentTryFindObject
Methode zurückgegeben wird? Tupel scheinen eher ein faules Paradigma für Programmierer zu sein, die sich nicht die Zeit nehmen möchten, ein Objekt zu definieren, das mehrere Werte enthält. Das heißt, im Wesentlichen sind sowieso alle Tupel im Kern.Ich wollte nur die zuvor genannten Optionen zusammenfassen und einige neue hinzufügen:
Oder Sie kombinieren diese Optionen:
Stellen Sie mehrere überladene Versionen Ihres Getters bereit, damit der Anrufer entscheiden kann, welchen Weg er einschlagen möchte. In den meisten Fällen hat nur der erste eine Implementierung des Suchalgorithmus, und die anderen umschließen nur den ersten:
Selbst wenn Sie nur eine Implementierung bereitstellen, möchten Sie möglicherweise eine solche Namenskonvention verwenden, um Ihren Vertrag zu verdeutlichen. Dies hilft Ihnen, falls Sie sich jemals dazu entschließen sollten, auch andere Implementierungen hinzuzufügen.
Sie sollten es nicht überbeanspruchen, aber es kann hilfreich sein, insbesondere beim Schreiben einer Hilfsklasse, die Sie in Hunderten verschiedener Anwendungen mit vielen verschiedenen Konventionen zur Fehlerbehandlung verwenden.
quelle
Expected<T> findObject(String)
woExpected<T>
die Funktionen hatorNull()
,orThrow()
,orSupplied(Supplier<T> supplier)
,orDefault(T default)
. Dies abstrahiert dasVerwenden Sie das Nullobjektmuster oder lösen Sie eine Ausnahme aus.
quelle
Person somePerson = personRepository.find("does-not-exist");
diese Methode gibt ein Nullobjekt für die ID zurückdoes-not-exist
. Wofür wäre dann das richtige VerhaltensomePerson.getAge()
? Derzeit bin ich noch nicht davon überzeugt, dass das Nullobjektmuster die richtige Lösung für die Suche nach Entitäten ist.Seien Sie konsistent mit den APIs, die Sie verwenden.
quelle
Vorteile einer Ausnahme:
Weitere Erläuterungen mit Beispielen finden Sie unter: http://metatations.com/2011/11/17/returning-null-vs-throwing-an-exception/
quelle
Es hängt davon ab, ob Ihre Sprache und Ihr Code für Folgendes werben: LBYL (schauen Sie, bevor Sie springen) oder EAFP (leichter um Vergebung zu bitten als um Erlaubnis)
LBYL sagt, Sie sollten nach Werten suchen (also eine Null zurückgeben)
EAFP sagt, Sie sollen einfach die Operation versuchen und sehen, ob sie fehlschlägt (eine Ausnahme ).
obwohl ich oben einverstanden bin .. Ausnahmen sollten für Ausnahme- / Fehlerbedingungen verwendet werden, und die Rückgabe einer Null ist am besten, wenn Prüfungen verwendet werden.
EAFP vs. LBYL in Python:
http://mail.python.org/pipermail/python-list/2003-May/205182.html ( Webarchiv )
quelle
Fragen Sie sich einfach: "Ist es ein Ausnahmefall, dass das Objekt nicht gefunden wird?" Wenn dies im normalen Verlauf Ihres Programms erwartet wird, sollten Sie wahrscheinlich keine Ausnahme auslösen (da es sich nicht um ein außergewöhnliches Verhalten handelt).
Kurzversion: Verwenden Sie Ausnahmen, um außergewöhnliches Verhalten zu behandeln, nicht um den normalen Kontrollfluss in Ihrem Programm zu behandeln.
-Alan.
quelle
Ausnahmen beziehen sich auf Design by Contract.
Die Schnittstelle eines Objekts ist eigentlich ein Vertrag zwischen zwei Objekten, der Anrufer muss den Vertrag erfüllen, sonst kann der Empfänger nur mit einer Ausnahme ausfallen. Es gibt zwei mögliche Verträge
1) Alle Eingaben der Methode sind gültig. In diesem Fall müssen Sie null zurückgeben, wenn das Objekt nicht gefunden wird.
2) nur eine Eingabe ist gültig, dh die, die zu einem gefundenen Objekt führt. In diesem Fall MÜSSEN Sie eine zweite Methode anbieten, mit der der Anrufer feststellen kann, ob die Eingabe korrekt ist. Zum Beispiel
WENN und NUR WENN Sie beide Methoden des 2. Vertrages angeben, dürfen Sie eine Ausnahme auslösen, wenn nichts gefunden wird!
quelle
Ich ziehe es vor, nur eine Null zurückzugeben und mich darauf zu verlassen, dass der Anrufer angemessen damit umgeht. Die (mangels eines besseren Wortes) Ausnahme ist, wenn ich absolut "sicher" bin, dass diese Methode ein Objekt zurückgibt. In diesem Fall ist ein Fehler ein außergewöhnliches sollte und sollte werfen.
quelle
Kommt darauf an, was es bedeutet, dass das Objekt nicht gefunden wird.
Wenn es sich um einen normalen Zustand handelt, geben Sie null zurück. Dies ist nur etwas, das gelegentlich passieren kann, und die Anrufer sollten es überprüfen.
Wenn es sich um einen Fehler handelt, lösen Sie eine Ausnahme aus. Die Aufrufer sollten entscheiden, was mit der Fehlerbedingung eines fehlenden Objekts geschehen soll.
Letztendlich würde beides funktionieren, obwohl die meisten Leute es im Allgemeinen für eine gute Praxis halten, Ausnahmen nur dann zu verwenden, wenn etwas Außergewöhnliches passiert ist.
quelle
Hier noch ein paar Vorschläge.
Wenn Sie eine Sammlung zurückgeben, vermeiden Sie die Rückgabe von null. Geben Sie eine leere Sammlung zurück, wodurch die Aufzählung ohne vorherige Nullprüfung einfacher zu handhaben ist.
Mehrere .NET-APIs verwenden das Muster eines throwOnError-Parameters, der dem Aufrufer die Wahl lässt, ob es sich wirklich um eine Ausnahmesituation handelt oder nicht, wenn das Objekt nicht gefunden wird. Type.GetType ist ein Beispiel dafür. Ein weiteres häufiges Muster bei BCL ist das TryGet-Muster, bei dem ein Boolescher Wert zurückgegeben und der Wert über einen Ausgabeparameter übergeben wird.
Unter bestimmten Umständen können Sie auch das Nullobjektmuster berücksichtigen, das entweder eine Standardversion oder eine Version ohne Verhalten sein kann. Der Schlüssel ist, Nullprüfungen in der gesamten Codebasis zu vermeiden. Weitere Informationen finden Sie hier http://geekswithblogs.net/dsellers/archive/2006/09/08/90656.aspx
quelle
In einigen Funktionen füge ich einen Parameter hinzu:
True bedeutet werfen, false bedeutet, einen Fehlerrückgabewert zurückzugeben. Auf diese Weise hat jeder, der diese Funktion verwendet, beide Optionen. Der Standardwert sollte true sein, zum Nutzen derer, die die Fehlerbehandlung vergessen.
quelle
Geben Sie eine Null zurück, anstatt eine Ausnahme auszulösen, und dokumentieren Sie die Möglichkeit eines Null-Rückgabewerts in der API-Dokumentation. Wenn der aufrufende Code die API nicht berücksichtigt und nach dem Nullfall sucht, führt dies höchstwahrscheinlich ohnehin zu einer Art "Nullzeigerausnahme" :)
In C ++ kann ich mir drei verschiedene Varianten des Einrichtens einer Methode vorstellen, die ein Objekt findet.
Option A.
Gibt null zurück, wenn ein Objekt nicht gefunden werden kann. Schön und einfach. Ich würde mit diesem gehen. Die folgenden alternativen Ansätze richten sich an Personen, die Out-Params nicht hassen.
Option B.
Übergeben Sie einen Verweis auf eine Variable, die das Objekt empfangen soll. Die Methode hat eine Ausnahme ausgelöst, wenn ein Objekt nicht gefunden werden kann. Diese Konvention ist wahrscheinlich besser geeignet, wenn nicht wirklich erwartet wird, dass ein Objekt nicht gefunden wird. Daher wird eine Ausnahme ausgelöst, um anzuzeigen, dass es sich um einen unerwarteten Fall handelt.
Option C.
Die Methode gibt false zurück, wenn ein Objekt nicht gefunden werden kann. Der Vorteil gegenüber Option A besteht darin, dass Sie in einem klaren Schritt nach dem Fehlerfall suchen können:
quelle
Ich beziehe mich nur auf den Fall, in dem null nicht als außergewöhnliches Verhalten angesehen wird. Ich bin definitiv für die try-Methode. Es ist klar, dass Sie nicht "das Buch lesen" oder "schauen müssen, bevor Sie springen", wie hier gesagt wurde
also im Grunde genommen:
und dies bedeutet, dass der Code des Benutzers ebenfalls klar ist
quelle
Wenn es für den Clientcode wichtig ist, den Unterschied zwischen gefunden und nicht gefunden zu kennen, und dies ein Routineverhalten sein soll, ist es am besten, null zurückzugeben. Der Client-Code kann dann entscheiden, was zu tun ist.
quelle
Im Allgemeinen sollte null zurückgegeben werden. Der Code, der die Methode aufruft, sollte entscheiden, ob eine Ausnahme ausgelöst oder etwas anderes versucht werden soll.
quelle
Oder geben Sie eine Option zurück
Eine Option ist im Grunde eine Containerklasse, die den Kunden zwingt, Standfälle zu bearbeiten. Scala hat dieses Konzept, schauen Sie sich die API an.
Dann haben Sie Methoden wie T getOrElse (T valueIfNull) für dieses Objekt, die entweder das gefundene Objekt oder eine vom Client angegebene Allternative zurückgeben.
quelle
Lieber null zurückgeben -
Wenn der Anrufer es ohne Überprüfung verwendet, tritt die Ausnahme trotzdem genau dort auf.
Wenn der Anrufer wirklich nicht , es verwenden, Besteuern nicht er
try
/catch
Blockquelle
Leider ist JDK inkonsistent. Wenn Sie versuchen, auf einen nicht vorhandenen Schlüssel im Ressourcenpaket zuzugreifen, wird keine Ausnahme gefunden. Wenn Sie einen Wert von map anfordern, erhalten Sie null, wenn dieser nicht vorhanden ist. Daher würde ich die Antwort des Gewinners wie folgt ändern: Wenn der gefundene Wert null sein kann, dann eine Ausnahme auslösen, wenn er nicht gefunden wird, andernfalls null zurückgeben. Befolgen Sie also die Regel mit einer Ausnahme. Wenn Sie wissen möchten, warum der Wert nicht gefunden wird, lösen Sie immer eine Ausnahme aus.
quelle
Solange ein Verweis auf das Objekt zurückgegeben werden soll, sollte die Rückgabe von NULL gut sein.
Wenn es jedoch das ganze blutige Ding zurückgibt (wie in C ++, wenn Sie dies tun: 'return bla;' anstatt 'return & bla;' (oder 'bla' ist ein Zeiger), können Sie kein NULL zurückgeben, weil es ist nicht vom Typ 'Objekt'. In diesem Fall würde ich das Problem lösen, indem ich eine Ausnahme auslöse oder ein leeres Objekt zurückgebe, für das kein Erfolgsflag gesetzt ist.
quelle
Denken Sie nicht, dass irgendjemand den Overhead bei der Ausnahmebehandlung erwähnt hat - benötigt zusätzliche Ressourcen zum Laden und Verarbeiten der Ausnahme. Wenn es sich also nicht um ein echtes App-Killing- oder Prozessstopp-Ereignis handelt (in Zukunft würde dies mehr schaden als nützen), würde ich mich dafür entscheiden, a zurückzugeben Wert, den die aufrufende Umgebung nach eigenem Ermessen interpretieren könnte.
quelle
Ich stimme dem Konsens hier zu (geben Sie null zurück, wenn "nicht gefunden" ein normales mögliches Ergebnis ist, oder lösen Sie eine Ausnahme aus, wenn die Semantik der Situation erfordert, dass das Objekt immer gefunden wird).
Es gibt jedoch eine dritte Möglichkeit, die je nach Ihrer speziellen Situation sinnvoll sein kann. Ihre Methode könnte ein Standardobjekt in der Bedingung "nicht gefunden" zurückgeben, sodass der aufrufende Code sicher sein kann, dass er immer ein gültiges Objekt empfängt, ohne dass eine Nullprüfung oder ein Ausnahmefangen erforderlich ist.
quelle
Geben Sie eine Null zurück, Ausnahmen sind genau das: etwas, das Ihr Code tut, wird nicht erwartet.
quelle
Ausnahmen sollten außergewöhnlich sein . Geben Sie null zurück, wenn es gültig ist, eine Null zurückzugeben .
quelle
Wenn die Methode eine Sammlung zurückgibt, geben Sie eine leere Sammlung zurück (wie oben angegeben). Aber bitte nicht Collections.EMPTY_LIST oder so! (im Fall von Java)
Wenn die Methode ein einzelnes Objekt abruft, haben Sie einige Optionen.
Seien Sie vorsichtig, wenn Sie eine Null zurückgeben möchten. Wenn Sie nicht der einzige Programmierer im Projekt sind, erhalten Sie zur Laufzeit NullPointerExceptions (in Java oder was auch immer in anderen Sprachen)! Geben Sie also keine Nullen zurück, die beim Kompilieren nicht überprüft werden.
quelle
null
. Weitere Informationen finden Sie in der Antwort mit der höchsten Bewertung.Wenn Sie eine Bibliothek oder eine andere Klasse verwenden, die eine Ausnahme auslöst , sollten Sie erneut werfen sie erneut . Hier ist ein Beispiel. Example2.java ist wie eine Bibliothek und Example.java verwendet das Objekt. Main.java ist ein Beispiel für diese Ausnahme. Sie sollten dem Benutzer auf der aufrufenden Seite eine aussagekräftige Nachricht und (falls erforderlich) eine Stapelverfolgung anzeigen.
Main.java
Beispiel.java
Beispiel2.java
quelle
Das hängt wirklich davon ab, ob Sie erwarten, das Objekt zu finden oder nicht. Wenn Sie der Denkschule folgen, dass Ausnahmen verwendet werden sollten, um etwas anzuzeigen, dann ist eine Ausnahme aufgetreten:
Andernfalls geben Sie null zurück.
quelle