Wie unterrichten Sie Programmierern die Ausnahmebehandlung? Alle anderen Dinge sind einfach zu lernen - Datenstrukturen, ASP.NET, WinForms, WPF, WCF - Sie nennen es, alles kann einfach gelehrt werden.
Mit Ausnahmebehandlung, sie unterrichtend try-catch-finally ist nur die syntaktische Art der Ausnahmebehandlung.
Was Sie jedoch lernen sollten, ist: Welchen Teil Ihres Codes geben Sie in den Try- Block ein? Was tun Sie in dem catch - Block?
Lassen Sie es mich mit einem Beispiel veranschaulichen.
Sie arbeiten an einem Windows Forms-Projekt (einem kleinen Dienstprogramm) und haben es wie folgt mit drei verschiedenen Projekten entworfen.
- UILayer
- BusinessLayer
- DataLayer
Wenn bei DataLayer eine Ausnahme (z. B. das Laden eines XDocuments löst eine Ausnahme aus) ausgelöst wird (der UILayer ruft BusinessLayer auf, der wiederum den DataLayer aufruft), führen Sie einfach die folgenden Schritte aus
//In DataLayer
try {
XDocument xd_XmlDocument = XDocument.Load("systems.xml");
}
catch(Exception ex)
{
throw ex;
}
Was wird wieder in den BusinessLayer geworfen und was wird in UILayer abgefangen, wo ich es in die Protokolldatei schreibe?
Gehen Sie so bei der Ausnahmebehandlung vor?
Antworten:
Um die Ausnahmebehandlung zu erläutern, erläutern Sie das Konzept dahinter: Der Code, in dem ein Fehler häufig auftritt, weiß nicht, wie dieser Fehler richtig behandelt wird. Der Code, der weiß, wie er richtig behandelt wird, könnte die Funktion sein, die diesen aufgerufen hat, oder er könnte weiter oben im Aufrufstapel liegen.
Wenn Sie eine Routine schreiben, die eine Routine aufruft, die möglicherweise eine Ausnahme auslöst, setzen Sie den Aufruf in einen Try-Block und den Fehlerbehandlungscode in den Catch-Block. Wenn nicht, lassen Sie es in Ruhe und lassen Sie etwas über sich in der Aufrufliste den Fehler behandeln.
Das Sprichwort "catch ex, throw ex" ist keine gute Methode zur Ausnahmebehandlung, da es eigentlich nichts behandelt. Abhängig davon, wie das Ausnahmemodell in Ihrer Sprache funktioniert, kann dies sogar schädlich sein, wenn Stack-Trace-Informationen gelöscht werden, die Sie zum Debuggen des Problems hätten verwenden können. Lassen Sie die Ausnahme einfach den Aufrufstapel weiterleiten, bis sie eine Routine erreicht, die weiß, wie sie damit umgeht.
quelle
Wie die meisten Dinge werden Ausnahmen und Ausnahmebehandlungen für neue Programmierer wahrscheinlich wie eine Lösung auf der Suche nach einem Problem erscheinen, bis Sie zeigen, warum die scheinbar einfachere Lösung (C-Rückgabecodes und errno) so schlecht funktioniert. Ich würde damit beginnen, das Problem zu motivieren und in einen Kontext zu setzen. Zeigen Sie, wie die Fehlerbehandlung mithilfe von Rückkehrcodes oder globalen / statischen Variablen erfolgen kann. Dann geben Sie Beispiele, warum es nicht gut funktioniert. Führen Sie dann und nur dann Ausnahmen ein und erklären Sie, dass es sich um eine Form der Außerbandsignalisierung handelt. Der springende Punkt ist, dass das Standardverhalten, wenn Sie eine Ausnahme ignorieren, darin besteht, den Buck-up-Call-Stack an jemanden weiterzugeben, der dies kann damit umgehen.
Fazit: Wenn Sie zeigen, wie die Fehlerbehandlung in C durchgeführt wurde, verstehen die Schüler, wozu Ausnahmen wirklich gut sind, und warum das Abfangen von Ausnahmen, mit denen Sie nicht wirklich umgehen können, im Grunde die Art und Weise simuliert, wie die Dinge im Mittelalter getan wurden.
quelle
Ich würde mit Design-Richtlinien für Ausnahmen beginnen, die kurz sind und DO, DO NOT und AVOID enthalten. Es gibt auch die Gründe dafür.
In Ihrem Beispiel wäre der Revelvent-Abschnitt Wrapping Exceptions
Und würde erwarten, dass es so geschrieben wird. Beachten Sie, dass es fängt eine spezifische Ausnahme und versucht, Informationen hinzuzufügen, so dass eine aussagekräftigere Nachricht verbreitet wird. Beachten Sie auch, dass die innere Ausnahme für Protokollierungszwecke weiterhin beibehalten wird
UPDATE Kanini fragt ist es sogar direkt im Data Layer diesen Ausnahmeblock zu haben oder sollte die Überprüfung der Datei auf Business Layer zur Verfügung.
Zunächst möchte ich darauf hinweisen, dass die Begründung für das Umschließen von Ausnahmen die folgende ist
Also, wenn Sie das Gefühl, die haben eine höhere Schicht über die Datei überhaupt, dann sollten Sie Ihre Datenschicht wie folgt aussehen wissen sollten
Kein Versuch kein Fang.
Persönlich bin ich der Meinung, dass es eine gute Sache ist, nichts zu tun oder die Ausnahme zu verpacken, wenn Ihre Datenschicht nicht etwas Nützliches wie die Verwendung einer Standarddatei systems.xml, die eine Assembly-Ressource darstellt, kann. (
throw ex
in diesem Fall oder dem bevorzugtenthrow
auch, fügt aber keinen Wert hinzu). Dies bedeutet, dass Sie das Problem schnell beheben können, sobald Sie es identifiziert haben.In diesem speziellen Beispiel tritt außerdem das folgende Problem in XDocument.Load auf, das vier Ausnahmen auslösen kann
Wir können nicht sicher garantieren, dass der folgende Code keine FileNotFoundException auslöst, da er möglicherweise vorhanden ist, wenn wir die Existenzprüfung durchführen, und nicht mehr vorhanden ist, wenn wir ihn laden. Dies der Business-Schicht zur Verfügung zu haben, würde nicht helfen.
SecurityException ist noch schlimmer, da unter anderem, wenn ein anderer Prozess eine exklusive Dateisperre hat, die Fehlermeldung erst angezeigt wird, wenn Sie ihn zum Lesen öffnen, da es keine File.CanIOpenThis () - Methode gibt. Und wenn eine solche Methode existiert, haben Sie immer noch das gleiche Problem wie bei File.Exists
quelle
Lass uns eine Rolle spielen. (Dies ist kein Scherzbeitrag)
Sie sollten einen Workshop machen, in dem Sie die Anrufkette ausleben. Jede Person ist ein Objekt. Du brauchst ein paar Neulinge und ein paar Leute, die verstehen, dass das "Spiel" hilft.
Verwenden Sie ein wirklich einfaches Problem wie Datei-E / A. gui-> model-> file_io
Die Person, die der Dateileser ist, muss die nächste Person informieren ....
Tun Sie es zuerst mit Rückkehrcodes. (Post-It-Zettel verwenden?)
Wenn die Interaktionen nur "das sind, was der Code sagt", können Sie die Leute dazu bringen, zu erkennen, dass Ausnahmen außergewöhnlich sind.
Übergeben Sie für Rückkehrcodes einen Post-It-Zettel.
Für Ausnahmen werfen Sie Ihre Hände in die Luft und sagen Sie, was das Problem ist.
Lassen Sie sie dann "catch x, throw x" ausführen und sehen, dass die Diagnose "das Modell hatte eine Ausnahme" lautet.
Ich denke, das wird funktionieren, um die Leute zu schulen, die Sie haben, weil die Leute die Interaktionen mit anderen Leuten ziemlich gut verstehen.
quelle
Ich würde mir vorstellen, Ausnahmen zu verstehen, die Sie zuerst benötigen, um beispielsweise die Beziehung zwischen Kind und Eltern von Klassen zu verstehen. Wenn Sie verstehen, dass ein Kind Funktionen von einem Elternteil erben kann, kann es auf elementarer Ebene möglicherweise verstehen, dass ein Problem, das ein Kind nicht lösen kann, dieses Problem (Ausnahme) an sein Elternteil weiterleitet und es dem Elternteil überlässt damit.
Dies wird zu einer verketteten Beziehung, bis Sie an einen Ort gelangen, an dem etwas weiß, wie mit der Ausnahme umzugehen ist.
Und so weit es geht, ist dies der triviale Teil ... wenn ein Problem auftritt, muss etwas damit umgehen, damit das Programm nicht fatal beendet wird. Nachdem diese Ausnahme behandelt wurde, ist der finally-Block da, der unabhängig vom try-catch immer ausgeführt wird .
Ein gutes Beispiel hierfür könnte das Networking sein:
oder in Ausnahmefällen:
quelle
Geben Sie dem Neuling eine Anwendung, die eine sehr gute Ausnahmebehandlung bietet. Wirf irgendwo eine Ausnahme und lass sie mit Hilfe von Logs debuggen. Indem sie die Propogation von Exception verfolgen, sollten sie in der Lage sein, sie zu debuggen. Mache diese Übung 3 oder 4 mal. Entfernen Sie jetzt einfach alle Ausnahmebehandlungen aus dem Code und lassen Sie sie versuchen, die gleiche Ausnahme zu verfolgen.
Ich glaube, die Anerkennung für den Ausnahmebehandlungscode wird sofort gewürdigt.
quelle
IMO, Sie sollten denken, dass Ausnahmebehandlung und Ablaufsteuerungsanweisungen im Grunde gleich sind. Sie verwenden sie, um den Ablauf Ihrer Programme basierend auf dem aktuellen Zustand zu steuern. Der Unterschied besteht darin, dass die Ausnahmebehandlung nur dann reagiert, wenn ein Fehler (oder eine Ausnahme) auftritt.
quelle
Es würde wahrscheinlich keinem neuen Programmierer helfen, aber ich stellte fest, dass ich das Konzept der Ausnahmen viel besser verstand, als ich anfing, Monaden in der funktionalen Programmierung zu verwenden. Eine Monade zwingt Sie, jeden "Kanal" zu betrachten, durch den Daten in ein Programm gelangen oder aus einem Programm herausfließen können, da dies eine bequeme Abstraktion darstellt, um einen Teil dieses Datenflusses "zu verbergen".
Die Idee, dass eine Funktion verschiedene Ausgabetypen haben kann und eine Ausnahme wie ein Rückgabetyp mit höherer Priorität von der Funktion ist, ist ziemlich ordentlich.
Wohlgemerkt, ich verstehe, dass Ausnahmen in den meisten Sprachen nicht so funktionieren (Implementierungsdetails), aber im abstrakten Sinne ist das, was passiert.
quelle
Stellen Sie sich vor, ein Affe benutzt die Tastatur
Ich habe meinen Jungs immer gesagt, wenn sie Code schreiben, um so zu tun, als würde ein Affe im Tastenfeld sitzen und diese Anwendung verwenden.
Dies brachte ihnen bei, wie man alle möglichen Dinge vorwegnimmt:
Ich denke, es war das Wortbild, dass ein Affe nur Schlüssel knallte und tat, was er wollte, anstatt gut mitzugehen, was den Trick brachte. Es hat bei mir funktioniert.
quelle