Secondo me c'è una differenza tra restituire NULL, restituire qualche risultato vuoto (ad es. la stringa vuota o una lista vuota) e lanciare un'eccezione.
Normalmente utilizzo il seguente approccio. Considero una funzione o metodo f (v1, ..., vn) chiamata come l'applicazione di una funzione
f : S x T1 x ... x Tn -> T
dove S è lo "stato del mondo" T1, ..., Tn sono i tipi di parametri di input e T è il tipo di ritorno.
Per prima cosa provo a definire questa funzione. Se la funzione è parziale (cioè ci sono alcuni valori di input per i quali non è definita), restituisco NULL per segnalarlo. Questo perché voglio che il calcolo termini normalmente e dimmi che la funzione che ho richiesto non è definita sugli input dati. Utilizzando, ad es., Una stringa vuota come valore di ritorno è ambigua perché potrebbe essere che la funzione sia definita sugli input e la stringa vuota sia il risultato corretto.
Penso che il controllo extra per un puntatore NULL nel codice chiamante sia necessario perché stai applicando una funzione parziale ed è compito del metodo chiamato dirti se la funzione non è definita per l'input specificato.
Preferisco usare eccezioni per errori che non consentono di eseguire il calcolo (cioè non è stato possibile trovare alcuna risposta).
Ad esempio, supponiamo di avere un cliente di classe e voglio implementare un metodo
Customer findCustomer(String customerCode)
per cercare un cliente nel database dell'applicazione tramite il suo codice.
In questo metodo, vorrei
- Restituisce un oggetto di classe Customer se la query ha esito positivo,
- Restituisce null se la query non trova alcun cliente.
- Genera un'eccezione se non è possibile connettersi al database.
I controlli extra per null, ad es.
Customer customer = findCustomer("...");
if (customer != null && customer.getOrders() > 0)
{
...
}
fanno parte della semantica di quello che sto facendo e non vorrei semplicemente "saltarli" per rendere il codice più leggibile. Non penso sia una buona pratica semplificare la semantica del problema a portata di mano solo per semplificare il codice.
Naturalmente, dato che il controllo per null si verifica molto spesso, è buono se la lingua supporta una sintassi speciale per questo.
Vorrei anche prendere in considerazione l'utilizzo del pattern Null Object (come suggerito da Laf) finché posso distinguere l'oggetto nullo di una classe da tutti gli altri oggetti.