2009-04-24 12 views
7

Che senso ha inserire le asserzioni nel nostro codice? Quali sono i vantaggi della programmazione assertiva?Vantaggi della programmazione assertiva

private void WriteMessage(string message) 
{ 
    Debug.Assert(message != null, "message is null"); 

    File.WriteAllText(FILE_PATH, message); 
} 

Per esempio possiamo controllare la variabile messaggio e un'eccezione qui. Perché uso assert qui? O è un esempio sbagliato per vedere i benefici degli asseriti?

risposta

9

Supportano anche la filosofia del fail fast, spiegata in this article da Jim Shore.

1

Se esiste una pre-condizione specificata per il metodo per prendere un parametro di messaggio non nullo, allora si desidera che il programma FAIL non appena la pre-condizione non regge e la fonte del bug deve quindi essere riparato

Credo che le asserzioni siano più importanti quando si sviluppa un software critico per la sicurezza. E certamente preferiresti usare le asserzioni quando il software è stato formalmente specificato.

+0

Ho commentato questo perché segue i principi di progettazione del libro "Design by contract". Dove specifichi le tue funzioni pre e post condizione. Sebbene la condizione post normale sia tendenzialmente più complessa di quella pre-condizione a seconda del contesto. Solo per una mini risposta. Le asserzioni sono utili per cogliere le comunicazioni tra sviluppatori sullo sviluppatore o sulla mancanza di modalità di funzionamento dei moduli. Inoltre dovrebbe esserci una separazione tra il framework centrale del motore e anche l'area di input dell'utente da mixare a due insieme è follia. – Chad

1

Per un'eccellente discussione di asserzioni (e molti altri argomenti relativi alla costruzione del codice), vedere Code Complete di Steve McConnel. Dedica un intero capitolo all'uso efficace delle asserzioni.

1

Li uso per verificare che sia stata fornita una classe dipendente valida. per exmaple nel costruttore DI, di solito si accetta una sorta di classe esterna da cui si dipende per fornire un'azione o un servizio.

in modo da poter affermare (classRef! - null, "classRef non può essere nullo"); invece di aspettare che tu passi un messaggio a classRef e ottenere qualche altra eccezione come eccezione: violazione di accesso o qualcosa di altrettanto ambiguo che potrebbe non essere immediatamente obvioius dall'osservare il codice.

2

Un'importante distinzione da considerare è quali tipi di errori vorresti cogliere con le affermazioni. Uso spesso asserzioni per rilevare errori di programmazione (ad es. Chiamare un metodo con un parametro null) e un diverso meccanismo per gestire gli errori di convalida (ad es. Passare un numero di previdenza sociale di lunghezza errata). Per l'errore di programmazione rilevato con l'asserzione, voglio fallire velocemente. Per l'errore di convalida, voglio rispondere in modo meno drastico perché potrebbe essere normale che ci siano errori nei dati (ad esempio, un utente che esegue l'immissione di dati di qualche tipo). In questi casi la corretta gestione potrebbe essere quella di riportare l'errore all'utente e continuare a funzionare.

7

dove alcune persone scriverebbero:

/* 
* This can never happen 
*/ 

la sua molto più pratico di scrivere:

assert(i != -1); 

Mi piace usare afferma perché sono facilmente disattivati ​​con un semplice momento della compilazione costante o fatta fare qualcos'altro come preparare un rapporto di errore. Di solito non lascio le affermazioni attivate (almeno, non nel solito modo) quando si rilascia qualcosa.

Usarli mi ha salvato dagli errori molto stupidi sui computer di altre persone .. quelle anime coraggiose che si divertono a testare il mio codice alfa. Usarli insieme a strumenti come valgrind aiuta a garantire che io prenda qualcosa di orribile prima di commetterlo.

0

È molto utile verificare le nostre ipotesi. Asserisce costantemente che l'invariante sia vero.In breve è utilizzato per i seguenti scopi,

  • Esso consente di implementare fail-fast sistema.
  • E riduce la propagazione dell'errore a causa di effetti collaterali.
  • Impedisce (tipo di controllo di integrità) al sistema di immettere uno stato incoerente a causa di dati dell'utente o successive modifiche al codice.

A volte, preferisco utilizzare assert_return() quando non vogliamo utilizzare try/catch/throw.

private void WriteMessage(string message) 
{ 
    assert_return(message != null, "message is null"); // return when false 
    File.WriteAllText(FILE_PATH, message); 
} 

Suggerisco assert_return() di arrestare l'applicazione segnalando un errore nel build di test. E poi nel sistema di produzione, dovrebbe log ed errori e tornare dalla funzione dicendo che non può farlo.

Problemi correlati