Meiner Meinung nach gibt es einen Unterschied zwischen der Rückgabe von NULL, der Rückgabe eines leeren Ergebnisses (z. B. der leeren Zeichenfolge oder einer leeren Liste) und dem Auslösen einer Ausnahme.
Normalerweise gehe ich folgendermaßen vor. Ich betrachte eine Funktion oder Methode f (v1, ..., vn) als die Anwendung einer Funktion
f : S x T1 x ... x Tn -> T
Dabei ist S der "Zustand der Welt" T1, ..., Tn die Art der Eingabeparameter und T der Rückgabetyp.
Ich versuche zuerst, diese Funktion zu definieren. Wenn die Funktion partiell ist (dh es gibt einige Eingabewerte, für die sie nicht definiert ist), gebe ich NULL zurück, um dies zu signalisieren. Dies liegt daran, dass die Berechnung normal beendet werden soll und ich weiß, dass die von mir angeforderte Funktion für die angegebenen Eingaben nicht definiert ist. Die Verwendung einer leeren Zeichenfolge als Rückgabewert ist beispielsweise nicht eindeutig, da die Funktion möglicherweise an den Eingängen definiert ist und die leere Zeichenfolge das richtige Ergebnis darstellt.
Ich denke, die zusätzliche Prüfung für einen NULL-Zeiger im aufrufenden Code ist notwendig, weil Sie eine Teilfunktion anwenden und es die Aufgabe der aufgerufenen Methode ist, Ihnen mitzuteilen, ob die Funktion für die angegebene Eingabe nicht definiert ist.
Ich bevorzuge Ausnahmen für Fehler, bei denen die Berechnung nicht möglich ist (dh es konnte keine Antwort gefunden werden).
Angenommen, ich habe eine Klasse Customer und möchte eine Methode implementieren
Customer findCustomer(String customerCode)
in der Anwendungsdatenbank nach einem Kunden anhand seines Codes suchen. Bei dieser Methode würde ich
- Rückgabe eines Objekts der Klasse Customer bei erfolgreicher Abfrage,
- Geben Sie null zurück, wenn die Abfrage keinen Kunden findet.
- Eine Ausnahme auslösen, wenn keine Verbindung zur Datenbank hergestellt werden kann.
Das Extra prüft auf null, z
Customer customer = findCustomer("...");
if (customer != null && customer.getOrders() > 0)
{
...
}
sind Teil der Semantik dessen, was ich tue, und ich würde sie nicht einfach "überspringen", um den Code besser lesbar zu machen. Ich halte es nicht für eine gute Praxis, die Semantik des vorliegenden Problems zu vereinfachen, nur um den Code zu vereinfachen.
Natürlich ist es gut, wenn die Sprache eine spezielle Syntax unterstützt, da die Überprüfung auf Null sehr häufig auftritt.
Ich würde auch erwägen, das Nullobjektmuster (wie von Laf vorgeschlagen) zu verwenden, solange ich das Nullobjekt einer Klasse von allen anderen Objekten unterscheiden kann.