La risposta di Ixrec è buona, ma avrò un approccio diverso perché credo che valga la pena di essere preso in considerazione. Ai fini di questa discussione parlerò delle asserzioni, dal momento che questo è il nome con cui il Preconditions.checkNotNull()
è stato tradizionalmente conosciuto.
Quello che vorrei suggerire è che i programmatori spesso sovrastimano il grado con il quale sono certi che qualcosa si comporterà in un certo modo e sottovaluteranno le conseguenze di ciò che non si comporta in quel modo. Inoltre, i programmatori spesso non realizzano il potere delle asserzioni come documentazione. Successivamente, nella mia esperienza, i programmatori affermano le cose molto meno spesso di quanto dovrebbero.
Il mio motto è:
The question you should always be asking yourself is not "should I
assert this?" but "is there anything I forgot to assert?"
Naturalmente, se sei assolutamente sicuro che qualcosa si comporta in un certo modo, ti asterrai dal sostenere che in effetti si è comportato in quel modo, e questo è per il la maggior parte parte ragionevole. Non è davvero possibile scrivere software se non ci si può fidare di nulla.
Ma ci sono eccezioni anche a questa regola. Curiosamente, per prendere l'esempio di Ixrec, esiste un tipo di situazione in cui è perfettamente desiderabile seguire int i = 3;
con un'affermazione che i
è effettivamente all'interno di un certo intervallo. Questa è la situazione in cui i
è suscettibile di essere alterato da qualcuno che sta provando vari scenari ipotetici, e il codice che segue si basa su i
con un valore all'interno di un certo intervallo, e non è immediatamente evidente da subito guardando il seguente codice qual è l'intervallo accettabile. Quindi, int i = 3; assert i >= 0 && i < 5;
potrebbe a prima vista sembrare insensato, ma se ci pensi, ti dice che puoi giocare con i
, e ti dice anche l'intervallo entro il quale devi rimanere. Un'asserzione è il miglior tipo di documentazione, perché è applicata dalla macchina , quindi è una garanzia perfetta e viene rifattorizzato insieme a il codice , quindi rimane sempre pertinente.
Il tuo esempio di getUser(int id)
non è un parente concettuale molto distante dell'esempio di assign-constant-and-assert-in-range
. Vedete, per definizione, gli errori si verificano quando le cose mostrano un comportamento diverso dal comportamento che ci aspettavamo. È vero, non possiamo affermare tutto, quindi a volte ci sarà un po 'di debug. Ma è un fatto ben noto nel settore che più rapidamente si ottiene un errore, meno costa. Le domande che dovresti porre non solo sono sicure di quanto getUser()
non restituirà mai null, (e non restituirà mai un utente con un nome null), ma anche, quali tipi di cose brutte accadranno con il resto del codice se in effetti un giorno restituisce qualcosa di inaspettato e quanto è facile guardare rapidamente il resto del codice per sapere esattamente cosa ci si aspettava da getUser()
.
Se il comportamento imprevisto causerebbe il danneggiamento del database, allora forse dovresti affermare anche se sei sicuro al 101% che non accadrà. Se un nome utente null
causerebbe qualche strano errore irreversibile criptico, migliaia di righe più in basso e miliardi di cicli di clock successivi, allora forse è meglio fallire il prima possibile.
Quindi, anche se non sono in disaccordo con la risposta di Ixrec, ti suggerirei di considerare seriamente il fatto che le affermazioni non costano nulla, quindi non c'è davvero nulla da perdere, solo da guadagnare, usandole liberamente.