Halten Sie diese Technik "SCHLECHT"?
Manchmal müssen Sie überspringen die Ausführung eines Teils einer Methode unter bestimmten, nicht-kritische Fehlerbedingungen. Sie können Ausnahmen, aber Ausnahmen sind generell nicht empfohlen bei normaler Anwendung der Logik, der nur für abnormale Situationen.
Also ich weiß einen trick, wie diese:
do
{
bool isGood = true;
.... some code
if(!isGood)
break;
.... some more code
if(!isGood)
break;
.... some more code
} while(false);
..... some other code, which has to be executed.
Verwende ich ein "fake" - Schleife wird einmal ausgeführt, und ich kann Sie Abbrechen, indem Sie Pause oder weiter.
Einige meiner Kollegen nicht mochte, und Sie nannten es "bad practice". Ich persönlich finde diesen Ansatz ziemlich glatt. Aber was denken Sie?
- Wollen Sie zum Bearbeiten des Titels, so ist es zumindest Hinweise auf das Thema? Ich will nicht, es zu ändern, um die Worte in den Mund, aber es sollte zeigen, etwas nützliches in der Frage Listen.
- Warum Prüfen "isGood" mehrmals ? ist es wahrscheinlich sein veränderte meinen anderen thread zum Beispiel ?
- Denn er werde es ändern, manchmal in den code.
- Ich persönlich bin eher abgeschreckt durch die wiederholte Verwendung von "isGood" als durch die Verwendung der "Pause". Wenn es 2 Punkte, an denen Dinge unGood, Chancen sind, gibt es 2 verschiedene Gründe. Wenn die Nötigung jeweils in eine boolean hinzufügen würde, beliebigen code auf alle, dann machen nur "Pause" davon abhängig was auch immer.
- Btw, wenn die Kollegen ehrlich behaupten, dass Sie nicht Lesen können, Ihren code, dann haben Sie ein problem, auch in den (seltenen) Fall, dass du vollkommen Recht und Sie Unrecht. Code muss lesbar sein, um mindestens 95% der Programmierer, nicht nur die 50%, die nicht Angst, kontrolliert nach vorne springt.
- Tun hüten Sie sich jedoch vor Menschen, die sagen: "das ist schlechte Praxis", wenn die Wahrheit ist, "ich hätte es getan anders".
- Ich habe gesehen und verwendet, wenn es eine komplexe Ressource Erwerb des Betriebes, in dem, wenn einer der Schritte, die rückgängig gemacht werden, wenn etwas fehlgeschlagen ist.
- Try/catch-Lösung scheint nicht Recht, sondern auch eine elegante alternative, springen Probleme hat, weil der Destruktor nicht aufgerufen werden. Am Liebsten würde ich Faktor aus dem code in ein eigenes Verfahren und verwenden statt.
- es scheint mir, dass die variable isgood ist unnötig - einfach nur "Pause" direkt
Du musst angemeldet sein, um einen Kommentar abzugeben.
Schlechte Praxis ist, es hängt davon ab.
Was sehe ich in diesem code ist eine sehr kreative Art und Weise zu schreiben "goto" mit weniger Schwefel riechenden keywords.
Gibt es mehrere alternativen, um dieser code, was kann oder kann nicht besser sein, je nach situation.
Ihre do - /while-Lösung
Deine Lösung ist interessant, wenn Sie haben eine Menge code, aber wertet den "beenden" - dieser Verarbeitung auf einige Punkte beschränkt:
Das problem ist, dass man nicht einfach mit dem "wenn(ISTFEHLER) break ;" ist eine Schleife, denn es wird nur verlassen Sie die innere Schleife, die nicht Ihre do - /while-block.
Und natürlich, wenn der Fehler innerhalb einer anderen Funktion, die Funktion muss wieder eine Art von Fehler-code, und der code darf nicht vergessen, zu interpretieren, den Fehlercode richtig.
Werde ich nicht diskutieren, alternativen mit ifs oder sogar verschachtelte ifs, da, nach einiger überlegung, finde ich Sie schlechter als Lösungen, als Ihre eigenen für Ihr problem.
Aufruf eines goto ein... goto
Vielleicht sollte man klar auf dem Tisch der Tatsache, du bist mit einem "goto", und dokumentieren Sie die Gründe, warum Sie diese Lösung wählen über eine andere stellen.
Zumindest, es wird sich zeigen etwas falsch sein könnte mit den code-und prompt Rezensenten zu bestätigen oder ungültig Ihre Lösung.
Müssen Sie noch eine offene block -, und, anstatt zu brechen, verwenden Sie die goto-Funktion.
Diese Weise, wie Sie den block beenden durch die springen, gibt es keinen Weg für Sie teilweise zu umgehen Objekt-Konstruktor mit dem springen (was verboten ist von C++).
Dieses problem löst der Prozess beenden von verschachtelten Schleifen problem (und mit goto zu verlassen verschachtelter Schleifen ist ein Beispiel von B. Stroustrup als eine gültige Verwendung von goto), aber Sie lösen nicht die Tatsache, einige Funktionen Anrufe konnte nicht und werden ignoriert (weil jemand nicht um zu testen, richtig Ihre Rückkehr-code, falls vorhanden).
Natürlich, jetzt Sie beenden Ihren Prozess von mehreren Punkten, die von mehreren loop-schachtelungstiefe, also, wenn es ein problem...
try/catch -
Wenn der code soll nicht scheitern (so, Fehler ist außergewöhnlich), oder auch wenn die code-Struktur kann scheitern, aber ist zu Komplex, um zu beenden, dann wird der folgende Ansatz könnte deutlicher sein:
Wenn eine Bedingung im code oben, oder im inneren einige Funktionen genannt, die von dem code oben, wird hier nicht erfüllt, dann wird eine exception zu werfen.
Dies ist etwas gewichtigeren als Ihre do - /while-Lösung, hat aber die gleichen Vorteile und können sogar zum Abbruch der Verarbeitung von innen-Schleifen oder innerhalb Funktionen aufgerufen.
Diskussion
Ihren Bedarf zu kommen scheint aus der Tatsache Sie kann haben einen komplexen Prozess ausgeführt (code, Funktionsaufrufe, Schleifen, etc.), aber Sie wollen zu unterbrechen, es über eine Bedingung (wahrscheinlich entweder scheitern, oder weil es gelang früher als ausgenommen). Wenn Sie können, schreiben Sie in einer anderen Weise, die Sie es tun sollten. Aber vielleicht gibt es keinen anderen Weg.
Angenommen.
, Wenn Sie können den code mit einem try/catch, tun Sie es: Zu unterbrechen, ein Komplexes Stück code, der eine Ausnahme auslösen, ist die richtige Lösung (die Tatsache, dass Sie können hinzufügen Misserfolg/Erfolg info in Ihrem Ausnahme-Objekt sollte nicht unterschätzt werden). Haben Sie eine klarere code danach.
Nun, wenn Sie in eine Geschwindigkeit Engpass, lösen Ihr problem mit geworfenen exceptions als exit ist nicht der Schnellste Weg, es zu tun.
Niemand kann leugnen, Ihre Lösung ist ein herrliches goto. Es wird nicht eine goto-spaghetti-code, weil die do/while wird nicht lassen Sie tun, aber es ist immer noch eine semantische springen. Dies können die Gründe, die einige finden konnte, ist dieser code "schlecht": Sie riechen die goto-ohne der Suche nach Ihrer Stichwort-klar.
In diesem Fall (und in dieser performance, profiliert-verified) Fall nur, deine Lösung scheint Ok, und besser als die alternative mittels if), aber von geringerer Qualität (IMHO) als die goto-Lösung, die zumindest nicht verstecken sich hinter einer falschen Schleife.
Abschluss
Soweit ich betroffen bin, finde ich deine Lösung ist kreativ, aber ich würde-stick, um die geworfene Ausnahme-Lösung.
So, in Reihenfolge der Präferenz:
Bist du ziemlich viel nur Verschleierung einer "goto" als fake-Schleife. Egal, ob Sie wie gotos oder nicht, du würdest genauso weit vorne mit Echtholz verkleidet springen.
Persönlich, ich würde einfach schreiben, wie
Warum verwenden Sie eine fake-Schleife? Sie können das gleiche tun mit einer Methode und werden Sie vermutlich nicht als "schlechte Praxis", wie es ist, mehr erwartet.
Haben Sie komplizierte nicht-lineare Ablaufsteuerung innerhalb eines schwer zu erkennen idiom. Also, ja, ich denke, dass diese Technik schlecht ist.
Könnte es sich lohnen, verbringen Sie irgendwann versuchen herauszufinden, ob diese geschrieben werden kann, ein wenig netter.
Dies ist verworren und verwirrend, würde ich es verschrotten, sofort.
Betrachten Sie diese alternativen:
Auch überlegen, brechen Sie den code oben in mehr als einer Methode.
Der Grund, warum dies funktioniert, ist durch so genannte short-circuit-Logik. Methode2 wird nicht aufgerufen, wenn die Methode1 der Wert false zurückgegeben.
Dies hat auch den zusätzlichen Vorteil, dass Sie kann brechen, Ihre Methode in kleinere Stücke, die einfacher zu unit-testen.
Was Sie zu tun versuchen, ist nicht lokal, Fehler bei der Wiederherstellung. Dies ist, was
goto
ist für. Es verwenden. (eigentlich ist das was exception-handling ist -- aber wenn Sie nicht verwenden können, dass 'goto' oder 'setjmp/longjmp' sind die nächste beste Sache).Diese Muster, die
if(succeeded(..))
Muster, und 'goto cleanup', allen 3 sind semantisch und strukturell gleichwertig. Je nachdem, was man am häufigsten in deinem code-Projekt. Es ist viel Wert in der Konsistenz.Ich würde Vorsicht gegen
if(failed(..)) break;
auf einen Punkt, dass Sie produzieren ein überraschendes Ergebnis, sollten Sie versuchen, nest Schleifen:Weder
goto cleanup
nochif(succeeded(..))
haben diese überraschung, so möchte ich ermutigen, mit einer dieser beiden statt.Grundsätzlich, die Sie gerade beschrieben springen. Ich benutze goto in C die ganze Zeit. Ich denke nicht, dass es schlecht ist, es sei denn, Sie es verwenden, um zu emulieren einer Schleife (nie tun!). Meine typische Verwendung von goto in C emulieren Ausnahmen (C hat keine Ausnahmen):
Außer der Tatsache, dass zu fangen und schließlich haben umgekehrter Reihenfolge, ich sehe nicht, warum dieser code soll SCHLECHT sein, nur weil es verwendet wird springen, wenn ein try/catch/finally-code funktioniert genau wie diese und eben nicht die Verwendung von goto. Das macht keinen Sinn. Und so sehe ich nicht, warum Ihr code sollte markiert sein, wie SCHLECHT.
Habe ich kein problem mit, dass, solange der code lesbar ist.
Habe ich dieses idiom für die Jahre. Ich finde es vorzuziehen, auf der ähnlich verschachtelten oder serielle ifs , die "onError goto", oder mehrere gibt. Das obige Beispiel mit den geschachtelten Schleife ist etwas aufpassen. Ich immer fügen Sie einen Kommentar über das "tun" um klar zu machen, jemand neues zu der Redewendung.
Für besser oder schlechter, ich habe das Konstrukt in ein paar Orte. Der start es ist klar dokumentiert, obwohl:
Dies ist in C anstatt in C++ - also Ausnahmen nicht eine option. Wenn ich mit C++, ich würde ernsthaft erwägen, mit Ausnahmen, die Ausnahmen behandeln. Der wiederholte test idiom vorgeschlagen von Jeremy ist auch vernünftig; ich verwendet haben, dass häufiger. RAII helfen würde mich sehr, zu; leider C nicht unterstützt, dass leicht. Und mit mehr Funktionen, würde helfen. Umgang mit Pausen innerhalb der geschachtelten Schleife erfolgt durch das wiederholte testen.
Ich würde nicht klassifizieren Sie es als einen großen Stil; ich würde nicht automatisch kategorisieren es als "SCHLECHT".
Umgestalten. Die saubere Lösung in den meisten Fällen zu splitten, diesen code in eine kleinere Helfer-Funktion aus, die Sie zurückgeben können, anstatt zu brechen aus Ihrem nicht-eigentlich-ein-Schleife.
Dann können Sie ersetzen Ihre Pause ist für die Rückkehr ist, und die Leute können sofort Sinn von deinem code, wenn Sie ihn Lesen, anstatt zu stoppen und sich Fragen, warum Sie aus dieser Schleife, die ja eigentlich nicht Schleife.
Ja, würde ich sagen, weil es einfach nicht so Verhalten, wie die Leser es erwarten würde, es ist eine schlechte Praxis. Das Prinzip der geringsten überraschung, und so weiter. Wenn ich sehe, eine Schleife, ich erwarte, dass es, um eine Schleife, und wenn es nicht klappt, ich habe zu stoppen und Frage mich warum.
Es hängt davon ab, was die alternativen sind. Sie müssen zugeben, dass der code, den Sie geschrieben ist etwas hässlich. Ich würde nicht sagen, dass es klar ist. Es ist eine Art hack. Also, wenn mit einer anderen Codierung-Lösung schlechter wäre, dann ok. Aber wenn Sie haben bessere alternative, lassen Sie sich nicht die Ausrede "es ist gut genug" Komfort, den Sie.
Seine ein sehr seltsames idiom. Es verwendet einen loop für die etwas seiner nicht vorgesehen und kann zu Verwechslungen führen. Ich könnte mir vorstellen, das wird mehr als eine Seite erstrecken, und es wäre eine überraschung für die meisten Menschen, dass dies nie mehr als einmal ausgeführt werden.
Wie über die Verwendung von üblichen Sprachfeatures wie Funktionen?
Ich würde dies schlechte Praxis. Ich denke, es wäre mehr Redewendungen, und in der Regel klarer, wenn Sie aus dieser eine Funktion geändert und die Pausen gibt.
Teilen Sie den code in kleinere Stücke, funktionale Elemente - so könnte man split oben in eine Funktion, die zurückgibt, anstatt zu brechen.
Ich weiß nicht, ob der oben ist schlechte Praxis, aber die Lesbarkeit ein wenig aus und kann verwirrend sein, um andere, die möglicherweise zur Aufrechterhaltung der Quelle.
Mir, was Sie tun, ist schlecht auf so viele weisen. Die Schleife kann ersetzt werden, indem Sie den code in eine Methode.
Ich persönlich glaube, dass, wenn Sie setzen einen ! vor Ihrer Konditionen, dann sind Sie auf der Suche für die falsche Sache. Für die Lesbarkeit machen Sie Ihre boolean match, was Sie für die überprüfung. Sie sind wirklich zu prüfen, ob es ein Fehler oder ein schlechter Zustand, so würde ich vorziehen:
über
So überprüfen Sie für das, was Sie wirklich wollen, zu überprüfen und halten Sie die Ausnahme Kontrollen auf ein minimum. Ihr Ziel sollte sein, readibility mehr als schwierig. Denken Sie an die Arme Seele, die ist zu haben, zu kommen und erhalten Sie Ihren code.
Eines der ersten Dinge, die ich gearbeitet habe vor 28 Jahren wurde ein Fortran-Programm, das immer benötigt, um zu überprüfen, ob es ein Grafik-Gerät zur Verfügung. Jemand, der aus dem grand-Entscheidung zum Aufruf der boolean für das LNOGRAF, so dass, wenn es einem Grafik-Gerät verfügbar, das wäre falsch. Ich glaube, es wurde so festgelegt, da von einer falschen Effizienz, die Prüfung für das Gerät zurückgegeben null, wenn es eine Grafik-Gerät. In dem gesamten code aller Kontrollen zu sehen waren, wenn der Grafik-Gerät verfügbar war. Es war voll:
If (.NICHT. LNOGRAF)
Ich glaube nicht, dass es eine einzige:
Wenn (LNOGRAF)
im Programm. Dies war in mission planning-software für die B-52 ' s und cruise missiles. Es ist definitiv lehrte mich die Namen meiner Variablen für das, was ich mir wirklich für die überprüfung.
Was ist mit einem funktionalen Ansatz?
Ich würde sagen, dass Ihre Lösung die richtige Lösung sein, aber es hängt davon ab. Paul Tomblin gepostet hat, eine Antwort, die besser ist (eine Reihe von if-Rohre) ... ob es verwendet werden kann.
Paul ' s Lösung kann nicht verwendet werden, wenn teure Objekt Initialisierungen auf dem Weg durch die Schleife. Wenn die erstellten Objekte werden in späteren Schritten verwendet, die do-while (0) - Lösung besser.
Sagte, die Benennung von Variablen soll verbessert werden. Außerdem, warum die Wiederverwendung der "escape" - variable so viel? Stattdessen Falle jeden einzelnen Fehler explizit und brechen die Schleife, so dass es offensichtlich ist, was bewirkt, dass die Pause bei jedem Punkt.
Jemand anderes vorgeschlagen, mit der Funktion Anrufe. Wieder, kann dies nicht eine ideale Zersetzung, wenn Sie fügt hinzu, nicht mehr benötigte Komplexität der Funktion Anrufe durch die Anzahl der Argumente, die übergeben werden können, bei jedem Schritt.
Andere haben vorgeschlagen, das ist eine schwierig zu verstehen idiom. Nun, zuerst könnte man einen Kommentar, wie vorgeschlagen, an den Anfang der Schleife. Zweite, do-while(0) ist eine normale und alltägliche Redewendung in Makros, die alle C-Programmierer sollte sich sofort erkennen, so dass ich einfach nicht kaufen, dass.
Wenn Ihr code tut etwas anderes als die einfache Bedeutung der Konstrukte im Ort, es ist ein gutes Zeichen, Sie haben gewagt, in die "niedlichen" Gebiet.
In diesem Fall haben Sie eine "Schleife", die wird nur einmal ausgeführt. Jeder Leser der code tun müssen, wird eine Doppel-nehmen, um herauszufinden, was Los ist.
Wenn der Fall, wo es nicht "gut" ist wirklich außergewöhnlich, dann auslösen von Ausnahmen wäre die bessere Wahl.
Zuerst, wenn Sie wollen einfach nur eine Antwort, ob diese code-Struktur oder idiom ist "bad", würde ich denken, es ist. Ich denke aber, das ist ein symptom für schlechte Zersetzung statt, ob der code, den Sie haben, ist "gut" oder "schlecht".
Ich würde denken, viel besser Analyse und refactoring durchgeführt werden, um in der Lage sein, um weitere Adresse, die Quelle des Problems, anstatt nur auf den code. Wenn man etwas tun kann, wie:
Dann denke ich, es wäre mehr "lesbar" und weitere Redewendungen. Auf diese Weise können Sie Funktionen wie:
Erhalten Sie den Vorteil der besseren Zersetzung und Hilfe vom compiler, um die erforderlichen kurzen-Schaltung, die &&'s bringt. Der compiler kann auch in-line-code in den Funktionen zu produzieren besseren code, als wenn Sie Sie die hand-codiert-Schleife.
Ist nichts falsch mit der Verwendung von Ausnahmen. Ausnahmen sind Teil der Anwendungslogik. Die Richtlinie über die Ausnahmen ist, dass Sie relativ selten zur Laufzeit.
Ich denke, dass es nichts grundsätzlich falsch mit der Technik. Ich denke, ich würde stellen Sie sicher, dass die bool mit dem Namen etwas mehr beschreibenden als isGood. Obwohl, jetzt wo ich Blick auf es, warum sollte es nicht funktionieren, um alle der code in der Schleife in einem einzigen if(!isGood) blockieren? Die Schleife wird nur einmal ausgeführt.
Wenn aufteilen code zwischen if(!isGood) break; in separate Funktionen, kann man am Ende mit Dutzenden von Funktionen mit nur ein paar Zeilen, so dass die Täter nicht vereinfachen alles. Ich konnte nicht verwenden zurück, weil ich nicht bereit bin, um die Funktion zu verlassen, es ist immer noch stuf ich will es tun.
Ich akzeptiere, dass wahrscheinlich sollte ich einfach zufrieden separate wenn(isGood) {...} Bedingung für jedes code-Teil, das will ich ausführen, aber manchmal, das würde dazu führen, EINE MENGE von geschweiften Klammern. Aber ich denke, ich akzeptiere, dass die Leute nicht wirklich wie diese Art von Aufbau, so dass die Bedingungen für alles, was Winde!
Vielen Dank für Eure Antworten.
Einen meta-Kommentar:
Wenn Sie Sie Kodieren, sollte Ihr Ziel klar sein, wartbaren code first. Sie sollten nicht aufgeben, die Lesbarkeit auf dem altar der Effizienz, es sei denn, Sie erstellen ein Profil und beweisen, dass es notwendig ist, und dass es tatsächlich verbessert die Dinge. Jedi mind tricks sollte vermieden werden. Denke immer, dass der nächste Kerl, den Sie zur Pflege Ihres code ist eine große mittlere psychopath mit Ihrer Haus-Adresse. Mich, zum Beispiel.
Ich glaube, ich würde Zustimmen, mit Ihren Kollegen, nur weil der Lesbarkeit, es ist nicht klar, atfirst Blick, was Sie versuchen zu erreichen, mit diesem code.
Warum nicht einfach
?
Ich glaube, die Leute sind nicht ehrlich.
Wenn ich, wie Sie Ihr team führen, würde der code wie diesem wären Sie für ein wenig eins zu eins, und als ein potentielles problem für das team, das Stück code ist besonders schrecklich.
Ich sagen, Sie sollten hören Sie auf Ihre Kolleginnen und Kollegen-und umschreiben nach den Anregungen hier gepostet.
Dies ist, was Ausnahmen sind für. Sie kann nicht fortgesetzt werden, da die Logik etwas falsch gelaufen ist. Auch wenn die Wiederherstellung ist trivial, es ist immer noch eine Ausnahme. Wenn Sie einen wirklich guten Grund für die nicht mit Ausnahmen, wie beim Programmieren in einer Sprache, die Sie nicht unterstützt, dann verwenden Sie die bedingte Blöcke, nicht Schleifen.