Domanda

Ad esempio quando si utilizza Preconditions.checkArgument , è il messaggio di errore dovrebbe riflettere il caso di passaggio o il caso in mancanza del controllo in questione?

import static com.google.common.base.Preconditions.*;

void doStuff(int a, int b) {
  checkArgument(a == b, "a == b");
  // OR
  checkArgument(a == b, "a != b");
}
È stato utile?

Soluzione

Per i controlli delle precondizioni, indicando il requisito nel messaggio di eccezione dettaglio è più informativo che semplicemente indicando i fatti. Inoltre porta ad un sacco più naturalmente la lettura del codice:

Il documentazione fornisce il seguente esempio:

  

In questo modo costrutti come

 if (count <= 0) {
   throw new IllegalArgumentException("must be positive: " + count);
 }
     

per essere sostituito con il più compatto

 checkArgument(count > 0, "must be positive: %s", count);

Due cose sono di nota:

  • L'esempio afferma chiaramente requisito, piuttosto che il fatto
    • " qualcosa deve essere destro ", invece di " qualcosa è sbagliato "
  • Invertendo la condizione di controllo, l'intero costrutto continua naturalmente

A seguito di questo esempio, un messaggio migliore sarebbe:

checkArgument(a == b, "a must be equal to b"); // natural!

Si può anche fare un passo ulteriore e catturare i valori di a e b nel messaggio di eccezione (vedi Effective Java 2nd Edition, Articolo 63: includere informazioni di cattura fallimento nei messaggi dettaglio ):

checkArgument(a == b, "a must be equal to b; instead %s != %s", a, b);

L'alternativa di dichiarare fatti è meno naturale di leggere nel codice:

checkArgument(a == b, "a != b");              // awkward!
checkArgument(a == b, "a is not equal to b"); // awkward!

Si noti come imbarazzante è da leggere in codice Java un'espressione booleana, seguito da una stringa che contraddice questa espressione.

Un altro aspetto negativo di fatti affermando è che per precondizioni complicato, è potenzialmente meno informativo, in quanto l'utente può già sapere del fatto, ma non ciò che le reali esigenze sono che è stato violato.

Domande correlate

Altri suggerimenti

La documentazione fornisce esempi che rendono molto chiaro con le parole al posto dei simboli:

checkArgument(count > 0, "must be positive: %s", count);

Dato che questi sono fondamentalmente solo andando essere messaggi di eccezione nei registri (o sessioni di debug), fare quello che pensa lo renderà più chiaro a tutti coloro che guardando problema, o chiunque legga il codice per capire la condizione preliminare.

Ad esempio, è potrebbe riscrivere quanto sopra come:

checkArgument(count > 0, "count must be positive; was actually %s", count);

Personalmente, per qualcosa di simile penso che avrei scritto

checkArgument(a == b, "a (%s) must equal b (%s)", a, b);

Spesso (la maggior parte del tempo) si può semplicemente utilizzare il metodo checkArgument () senza il parametro messaggio di errore, che è, non fornendo il messaggio di errore a tutti.

Per fare un buon messaggio di errore bisogna capire che leggeranno il messaggio. Non è l'utente finale; se il presupposto non indica molto probabilmente ad un bug nel codice. Il testo può spiegare la precondizione fallita, ma nella maggior parte dei casi è di alcuna utilità per l'utente finale, che si suppone essere un suggerimento per il programmatore. La maggior parte del tempo, il messaggio di per sé rende anche non ha senso senza un codice stacktrace e la fonte. Infatti, nella maggior parte dei casi, un codice stacktrace e la fonte è esattamente ciò che un programmatore ha bisogno di correggere un bug, il messaggio di errore non aiuta. Se il presupposto non è evidente, un commento accanto ad essa è un modo perfetto per documentarlo.

La necessità di fornire sempre un messaggio di errore nel caso nessuno veramente a cuore il testo porta a programmatori che fanno messaggi inutili, evidenti e non utili che rende solo il codice meno leggibile.

Ci sono alcuni casi, quando un messaggio di errore può essere utile, ad esempio, il messaggio può contenere i valori attuali delle variabili, ma dalla nostra esperienza che non è molto spesso, e in questi casi è possibile utilizzare il messaggio.

argomenti simili si applicano anche nei metodi ASSERISCE in JUnit; fornendo sempre un messaggio di errore non è una buona idea.

Inoltre, quando si utilizza presupposti in una biblioteca piuttosto che una richiesta per gli utenti finali, le cose potrebbero essere diverse dal momento che non si sa come verrà utilizzato il codice.

polygenelubricants sottolineato:

  

Per i controlli delle precondizioni, affermando l'esigenza nel messaggio di eccezione dettaglio è più informativo che semplicemente indicando i fatti.

Mentre si può certamente fare questo con Guava Presupposti, Requisiti API (che ho creato) consente per ottenere una migliore uscita senza alcuno sforzo da parte vostra.

Guava Presupposti

String a = "foosball";
String b = "ballroom";
Preconditions.checkArgument(a == b, "a == b");

ti dà questo:

java.lang.IllegalArgumentException: a == b
    at com.google.common.base.Preconditions.checkArgument(Preconditions.java:122)
    at Main.main(Main.java:142)

Requisiti API

String a = "foosball";
String b = "ballroom";
requireThat(a, "a").isEqualTo(b, "b")

ti dà questo:

uscita

Lo stesso ingresso, uscita migliore.

(Se il terminale non supporta i colori, si otterrà un testo diff invece)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top