Come insegnare Gestione delle eccezioni per i nuovi programmatori? [chiuso]

21

Come si fa a insegnare la gestione delle eccezioni ai programmatori. Tutte le altre cose vengono insegnate facilmente: Strutture dati, ASP.NET, WinForms, WPF, WCF: tu lo chiami, tutto può essere insegnato facilmente.

Con Exception Handling, insegnare loro try-catch-finally è solo la natura sintattica di Exception Handling.

Ciò che dovrebbe essere insegnato comunque è: quale parte del codice inserisci nel blocco prova ? Che cosa fai nel blocco catch ?

Lascia che ti illustri con un esempio.

Stai lavorando su un progetto Windows Form (una piccola utility) e lo hai progettato come di seguito con 3 diversi progetti.

  1. UILayer
  2. BusinessLayer
  3. DataLayer

Se un'eccezione (diciamo di caricare un XDocument genera un'eccezione) viene sollevata su DataLayer (l'UILayer chiama BusinessLayer che a sua volta chiama il DataLayer), esegui semplicemente la seguente

//In DataLayer
try {
    XDocument xd_XmlDocument = XDocument.Load("systems.xml");
} 
catch(Exception ex)
{
    throw ex;
}

che viene lanciato di nuovo nel BusinessLayer e che viene catturato in UILayer dove lo scrivo nel file di registro?

È così che si va a gestire le eccezioni?

    
posta Kanini 26.10.2010 - 18:21
fonte

9 risposte

29

Per spiegare la gestione delle eccezioni, spiega il concetto alla base: Il codice in cui si verifica un errore frequentemente non sa come gestirlo correttamente. Il codice che sa come gestirlo correttamente potrebbe essere il funzione che ha chiamato quella, o potrebbe essere più in alto nello stack delle chiamate.

Quando si scrive una routine che chiama una routine che potrebbe generare un'eccezione, se si sa come gestirlo correttamente, inserire la chiamata in un blocco try e inserire il codice di gestione degli errori nel blocco catch. In caso contrario, lascia stare e lascia che qualcosa sopra di te nella pila di chiamate gestisca l'errore.

Dire "catch ex, throw ex" è not un buon metodo per gestire le eccezioni, poiché in realtà non gestisce nulla. Inoltre, a seconda di come funziona il modello di eccezione nella tua lingua, questo può essere effettivamente dannoso se cancella le informazioni di traccia di stack che avresti potuto utilizzare per eseguire il debug del problema. Lascia che l'eccezione si propaghi nello stack delle chiamate finché non raggiunge una routine che sa come gestirlo.

    
risposta data 26.10.2010 - 18:28
fonte
13

Come la maggior parte delle cose, le eccezioni e la gestione delle eccezioni probabilmente sembreranno una soluzione alla ricerca di un problema per i nuovi programmatori finché non mostrerai perché la soluzione apparentemente più semplice (codici di ritorno in stile C ed errno) funziona così male. Vorrei iniziare motivando il problema e inserendolo nel contesto. Mostra come la gestione degli errori può essere eseguita utilizzando codici di ritorno o variabili globali / statiche. Quindi fornisci esempi del perché non funziona bene. Allora e solo allora, introducete le eccezioni e spiegate che sono una forma di segnalazione fuori banda e che l'intero punto è che il comportamento predefinito se ignorate un'eccezione è passare il tempo lo stack di chiamata a qualcuno che può gestirlo.

Conclusione: mostrare come la gestione degli errori è stata eseguita in C farà capire agli studenti in cosa consistono realmente le eccezioni e perché catturare eccezioni che non si possono realmente gestire simula sostanzialmente il modo in cui sono state fatte le cose nel Medioevo.

    
risposta data 29.10.2010 - 23:09
fonte
5

Vorrei iniziare con Linee guida di progettazione per le eccezioni il suo breve e include DO, DO NOT e EVITARE. Dà anche i motivi per cui.

Nel tuo caso di esempio la sezione del revelvent sarebbe Wrapping Exceptions

E si aspetterebbe che fosse scritto in questo modo. Si noti che rileva un'eccezione specifica e tenta di aggiungere informazioni in modo da propagare un messaggio più significativo. Si noti inoltre che l'eccezione interna viene ancora mantenuta per scopi di registrazione

//In DataLayer

try
{
XDocument xd_XmlDocument = XDocument.Load("systems.xml");
}
catch(FileNotFoundException ex)
{
        throw new TransactionFileMissingException(
                     "Cannot Access System Information",ex);
}

Aggiorna Kanini chiede che sia anche giusto avere questo blocco di eccezioni nel livello dati o il controllo che il file sia disponibile per Business Layer.

Innanzitutto vorrei sottolineare che la logica di Wrapping Exceptions è questa

Consider wrapping specific exceptions thrown from a lower layer in a more appropriate exception, if the lower layer exception does not make sense in the context of the higher-layer operation.

Quindi, se ritieni che un livello superiore debba conoscere il file, il tuo livello dati dovrebbe apparire come questo

//In DataLayer

XDocument xd_XmlDocument = XDocument.Load("systems.xml");

No Try No Catch.

Personalmente ritengo che a meno che il tuo livello dati non faccia qualcosa di utile come usare un sistema.xml predefinito che è una risorsa di assemblaggio, non fare nulla o avvolgere l'eccezione è una buona scommessa dato che la tua registrazione ti dirà quale metodo e quale file era il problema. ( throw ex in questo caso o anche il preferito throw lo fa ma non aggiunge alcun valore). Ciò significa che una volta identificato sarai in grado di risolvere rapidamente il problema.

Come parte di questo esempio particolare ha anche il seguente problema in quanto XDocument.Load può lanciare quattro execeptions

  • ArgumentNullException
  • SecurityException
  • FileNotFoundException
  • UriFormatException

Non possiamo garantire in modo sicuro che il seguente codice non getti e FileNotFoundException, semplicemente perché potrebbe esserci quando eseguiamo il controllo dell'esistenza e scompaiono quando vengono caricati. Avere quello disponibile per il livello aziendale non sarebbe di aiuto.

 if (File.Exists("systems.xml")) 
     XDocument.Load("systems.xml");

SecurityException è anche peggio perché, tra le altre ragioni per cui viene lanciata se un altro processo ha un blocco di file esclusivo, non otterrai l'errore finché non provi ad aprirlo per la lettura perché non esiste un metodo File.CanIOpenThis () . E se questo metodo esistesse hai ancora lo stesso problema con File.Exists

    
risposta data 27.10.2010 - 23:05
fonte
4

Facciamo un gioco di ruolo. (questo non è un post di scherzo)

Dovresti fare un seminario in cui reciti la catena di chiamate. Ogni persona è un oggetto. Avrai bisogno di alcuni neofiti e alcune persone che capiscono il "gioco" aiuta.

Usa un problema davvero semplice come il file IO. su GUI > modello- > file_io

La persona che è il lettore di file deve dirlo al prossimo ....

Per prima cosa fallo con i codici di ritorno. (usa note post-it?)

se le interazioni sono solo "ciò che dice il codice" abbastanza presto puoi far capire alla gente che le eccezioni sono eccezionali.

per i codici di ritorno, passa un post-it.

per le eccezioni, lancia le mani in aria e dì quale è il problema.

quindi fagli fare "prendere x, lanciare x" e vedere che la diagnosi è molto peggiore di ciò che la GUI ottiene "il modello ha avuto un'eccezione".

Penso che questo funzionerà per addestrare le persone che hai perché le persone capiscono le interazioni con le altre persone piuttosto bene.

    
risposta data 02.11.2010 - 23:43
fonte
1

Immaginerei di capire le eccezioni che devi prima capire, ad esempio, la relazione bambino / genitore delle classi. Se capisci che un bambino può ereditare funzionalità da un genitore, potrebbe essere in grado a livello elementare di capire che se un bambino ha un problema che non può gestire passerà questo problema (eccezione) al suo genitore e lascerà che il genitore accetti con esso.

Questa diventa una relazione concatenata finché non si finisce con un luogo in cui qualcosa sa come gestire l'eccezione.

E per quanto riguarda finalmente questa è la parte più banale ... quando si verifica un problema qualcosa deve gestirlo in modo che il programma non esca fatalmente, dopo che l'eccezione è gestita, il blocco finally è lì che verrà sempre eseguito indipendentemente il tentativo di cattura.

Un buon esempio di questo potrebbe essere il networking:

  • facciamo la connessione
  • La connessione
  • è ok, quindi la usiamo
  • al termine chiudiamo e liberiamo risorse

o in casi eccezionali:

  • crea una connessione
  • si verifica un'eccezione che qualcosa gestisce
  • a questo punto liberiamo la connessione e le risorse associate
risposta data 26.10.2010 - 18:57
fonte
1

Dai una Applicazione al principiante che ha un'ottima gestione delle eccezioni. Lancia qualche eccezione da qualche parte e falle fare il debug con l'aiuto di Log. Tracciando la propagazione di Eccezione dovrebbero essere in grado di eseguirne il debug. Fai questo esercizio 3 o 4 volte. Ora basta rimuovere tutta la gestione delle eccezioni dal codice e lasciare che provino a tracciare la stessa eccezione.

Credo che l'apprezzamento per il codice di Exception Handling sarà immediatamente apprezzato.

    
risposta data 02.11.2010 - 16:58
fonte
0

IMO, dovresti pensare che le istruzioni di gestione delle eccezioni e di controllo del flusso siano fondamentalmente le stesse. Li usi per controllare il flusso dei tuoi programmi in base alle condizioni in cui si trovano attualmente. La differenza è che la gestione delle eccezioni reagirà solo quando si verifica un errore (o un'eccezione).

    
risposta data 01.11.2010 - 16:22
fonte
0

Probabilmente non avrebbe aiutato un nuovo programmatore, ma ho scoperto che ho capito molto meglio il concetto di eccezioni una volta che ho iniziato a usare le monadi nella programmazione funzionale. Una monade ti costringe a considerare ogni "canale" attraverso il quale i dati possono entrare o uscire da un programma, poiché tutto ciò fornisce un'astrazione conveniente per "nascondere" parte di quel flusso di dati.

L'idea che una funzione possa avere diversi tipi di output, e un'eccezione è come un tipo di ritorno con priorità più alta dalla funzione è piuttosto accurato.

Intendiamoci, capisco che non è così che le eccezioni funzionano nella maggior parte del linguaggio (dettagli di implementazione), ma in senso astratto, questo è ciò che sta accadendo.

    
risposta data 04.11.2010 - 19:32
fonte
0

Fai finta che una scimmia stia usando la tastiera

Ero solito dire ai miei ragazzi quando stanno scrivendo il codice per fingere che una scimmia siederà al keyborad e userà questa applicazione.

Questo ha insegnato loro ad anticipare tutti i tipi di cose:

  • Dati mancanti
  • File mancanti
  • Caratteri alfa quando ti aspetti dei numeri
  • Divisione per zero

Penso che sia stata la parola immagine di avere una scimmia che batteva le chiavi e faceva quello che voleva invece di seguire bene quel trucco. Ha funzionato per me.

    
risposta data 06.11.2010 - 17:34
fonte

Leggi altre domande sui tag