Wartungstechnisch gesehen, gilt "else while" ohne eingreifende Zahnspangen als sicher?


26

Gilt die else whileWartung ohne dazwischenliegende Zahnspangen als "sicher"?

Schreiben von if-elseCode ohne geschweifte Klammern wie unten ...

if (blah)
    foo();
else
    bar();

... birgt ein Risiko, da das Fehlen von geschweiften Klammern es sehr einfach macht, die Bedeutung des Codes versehentlich zu ändern.

Ist unten aber auch riskant?

if (blah)
{
    ...
}
else while (!bloop())
{
    bar();
}

Oder gilt else whileohne dazwischenliegende Zahnspange "sicher"?


20
für mich else whilesieht es eklig aus. Ich würde verwenden else { while (condition) { ... } }.
Joachim Sauer

7
Ich denke, es ist zu subjektiv für eine richtige Antwort ... Ich selbst würde es nicht tun, da ich dort keine Schleife erwarte, und denke, ich erwarte nicht, die Lesbarkeit zu erschweren.
Johannes

7
Ich würde Methode für while-Zeug extrahieren
Mücke

12
Ehrlich gesagt macht es mir unheimlich. ifwird nur einmal ausgewertet, zeigt aber whileeine Schleife an, so dass ich durch das Verbinden von beiden ein unbegründetes Gefühl if
bekomme,

4
Und was ist, wenn Sie in der elseKlausel das tun while und etwas mehr tun wollen ? Verwenden Sie bitte nur Zahnspangen.
Carlos Campderrós

Antworten:


57

Das erinnert mich an diesen Code:

if ( ... ) try {
..
} catch (Exception e) {
..
} else {
...
}

Jedes Mal, wenn Sie zwei Arten von Blöcken kombinieren, geschweifte Klammern vergessen und die Einrückung nicht erhöhen, erstellen Sie Code, der nur schwer zu verstehen und zu warten ist.


18
Gutes Beispiel. Was für eine schreckliche Art, es zu schreiben.
Leo

4
Wow, diese Antwort ist lächerlich überzeugend!
Mehrdad

Sie können moderne IDEs ganz einfach so einrichten, dass Code beim Speichern automatisch formatiert wird - einschließlich des Einfügens von geschweiften Klammern und des Korrigierens des Einzugs. Das ist also nur ein halbes Argument. Richtig eingerückt würde dies die Lesbarkeit nicht beeinträchtigen, unabhängig davon, ob geschweifte Klammern vorhanden sind oder nicht.
Hans-Peter Störr

55

Vielleicht liegt es daran, dass ich meinen Beruf (vor langer Zeit ) mithilfe der Jackson-Entity-Structure-Diagram- Methode gelernt habe , aber ich bin der Ansicht, dass der einzig richtige nicht umrahmte Begriff nach einem ifoder einem elseein nachfolgender ist if(dh eine else ifLeiter zulassen ).

Alles andere (kein Wortspiel beabsichtigt) kann zu Missverständnissen und / oder Wartungsproblemen führen. Das ist der zentrale Aspekt der Idee des OP, "unsicher" zu sein.

Ich würde auch sehr käfig sein, wenn ich das while()in die gleiche Zeile wie das else- ob verspannt oder nicht - aufnehmen würde. Es liest sich für mich nicht richtig ... das Fehlen zusätzlicher Einrückungsmasken, die es ist, ist die elseKlausel. Und mangelnde Klarheit führt zu Missverständnissen (so).

In diesem Beispiel würde ich (und in meinem Team darauf bestehen) dringend Folgendes empfehlen:

if ( blah )
{
    ...
}
else
{
    while ( !bloop() )
    {
        bar();
    }
}

Natürlich würde ich auch passende Kommentare erwarten.

- Bearbeiten -

Vor kurzem litt Apple an einer SSL-Sicherheitsanfälligkeit, die durch einen schlechten Wartungsfix verursacht wurde und eine zweite Zeile zu einer nicht geschweiften einzelnen Zeile hinzufügte. Lassen Sie uns die Idee zu Bett bringen, dass ungerahmte einzelne Linien in Ordnung sind?


2
Ich bin damit einverstanden, ob es der einzig richtige Begriff ist, einem anderen zu folgen. Wenn es eine else whilegäbe, würde ich wahrscheinlich nicht einmal bemerken, dass es eine Schleife beim schnellen Überfliegen des Codes gibt, besonders wenn die gesuchte Bedingung vom if erfüllt wurde.
Drake Clarris

3
Es ist lustig. Jeder sagt, dass es einfacher ist zu lesen, wenn alles in geschweiften Klammern steht. Ich finde das Gegenteil wahr. Wenn es sich nur um eine Anweisung handelt, können Sie sie leichter lesen, wenn Sie sie nicht in geschweifte Klammern setzen. Weniger Unordnung. Es kann nur daran liegen, dass ich es immer so gemacht habe.
Jeff Davis

2
@ JeffDavis, das ist ein guter Fang. "Einfacher zu lesen" ist eine typische Einladung zum nutzlosen Heiligen Krieg. Ich für meinen Teil bevorzuge geschweifte Klammern, aber nicht wegen irrelevanten "easiertoread" -Mülls (für mich ist es zum Beispiel genau das Gegenteil), sondern weil es schwieriger ist, die weitere Code-Pflege einzuschränken. Durch die Art und Weise OP es Dinkel besser in ihrer Frage: ist else whileohne Klammer dazwischen als „sicher“ ?
gnat

@ JeffDavis - Ich weiß, dieser Thread ist zwei Jahre alt, aber Apple vor kurzem entdeckt, warum nicht mit Klammern ist keine gute Idee andrewbanks.com/…
Andrew

@Andrew Übrigens, Apples Swift-Sprache verbietet jetzt explizit die einzeilige Flusskontrolle. Dieser Fehler könnte einer der Gründe dafür sein.
Sulthan

6

Mir wurde immer beigebracht, alles in Klammern zu halten, eingerückt und kommentiert. Ich glaube, es ist viel einfacher, Fehler zu lesen und zu erkennen. Persönlich denke ich, dass Modularität der Schlüssel ist, also würde ich den Code immer so schreiben:

    if(blah)
    {
     ....
    }
    else
    {
       while(!bloop()
       {
        bar;
       }
    }

6

Ich würde Methode extrahieren und es machen

if ( blah )
{
    ...
}
else
{
   newMethod();
}

Siehe den auf der Refactoring-Katalog- Website erläuterten Ansatz "Methode extrahieren" :

Sie haben ein Codefragment, das zusammen gruppiert werden kann.

Verwandeln Sie das Fragment in eine Methode, deren Name den Zweck der Methode erklärt.

void printOwing() {
    printBanner();

    //print details
    System.out.println ("name:    " + _name);
    System.out.println ("amount    " + getOutstanding());
}

                                                                                                         http://www.refactoring.com/catalog/arrow.gif

void printOwing() {
    printBanner();
    printDetails(getOutstanding());
}

void printDetails (double outstanding) {
    System.out.println ("name:    " + _name);
    System.out.println ("amount    " + outstanding);
}

Hängt davon ab ... wenn zum Beispiel die while-Schleife Daten auf Funktionsebene verwendet, müssen Sie diese Daten jetzt auf Modulebene (oder Klasse, wenn Sie C ++ verwenden) erweitern. Und wenn Sie nur einen kleinen Code-Ausschnitt haben, sind Sie in triviale Methoden vertieft. Aber manchmal, abhängig von den Umständen, stimmte ich zu.
Andrew

1
+1 Intelligente C ++ - Compiler können eine Funktion einbinden. In .Net-Umgebungen sind kleine Funktionen aufgrund von JIT besser.
Job

4

Ich würde es als schlechte Angewohnheit betrachten, zu codieren. Manchmal funktioniert es einwandfrei und Sie werden kein Problem damit haben, den Code zu kompilieren und auszuführen. In anderen Fällen kann dies zu schwerwiegenden Fehlern führen, und Sie werden am Ende Stunden damit verbringen, diesen Fehler zu beheben.

Es wird immer empfohlen, Ihren Code zu modularisieren. Wenn Sie eine while-Schleife in einem anderen Teil einfügen müssen, setzen Sie sie in einen Block, damit andere beim Arbeiten an Ihrem Code die Logik leicht verstehen können.

if ( blah )
{
    ...
}
else
{
    while ( !bloop() )
    {
        bar();
    }
}

Es ist eine gute Praxis, Code in Blöcken zu platzieren. Es macht es einfacher und einfacher zu verstehen und zu debuggen.


4

Es könnte in Ordnung sein, wenn es so einfach bleibt, obwohl es mir persönlich nicht gefällt und ich es vorziehe, selbst für die einfachsten if / else-Codeblöcke geschweifte Klammern zu verwenden. Es ist nur ordentlicher für mich.

Dies ist jedoch problematisch, wenn Sie geschachtelt haben, wenn / else einige mit geschweiften Klammern, andere ohne, durchläuft. Eine While-Schleife mitten in all den Spaghetti! Ich habe mit so schlechtem Code gearbeitet und es ist ein Albtraum, Fehler zu beheben und zu verstehen. Dies folgt ab dem ersten Punkt. Es ist in Ordnung, wenn es einfach bleibt und Sie damit zufrieden sind, aber dann kommen andere Programmierer und fügen Dinge hinzu, wahrscheinlich ein if else innerhalb der while-Schleife. Wenn es an erster Stelle sauber geschrieben ist, ist die Wahrscheinlichkeit geringer, dass dies geschieht.

Es geht darum, Dinge klar zu machen, damit andere Programmierer auf einen Blick erkennen können, was richtig und was falsch ist. Schreiben Sie den Code so, dass das Muster richtig aussieht und nicht ruckelt.

Die Kehrseite davon ist, dass ich vielleicht einige Leute sehen könnte, die behaupten, dass dies in bestimmten Fällen gut liest. Wenn ich die Ressource habe, die ich für die weitere Verarbeitung benötige, während ich auf etwas warte, tue dies. Auch dann gibt es für mich keinen Unterschied darin, die while-Schleife im else-Block zu verschachteln.


3

Nun, obwohl alle über die Verwendung von Zahnspangen streiten und sie zu lieben scheinen, bevorzuge ich eigentlich das Gegenteil. Ich benutze Klammern nur, wenn ich muss, weil ich sie ohne besser lesbar und prägnant finde.

if (...)
   foo();
else while(...)
   bar();

... ich finde das wirklich " else while(...)" bemerkenswert lesbar! Es liest sich sogar wie normales Englisch! Aber ich denke, die Leute werden es alle seltsam finden, weil es gelinde gesagt ungewöhnlich ist.

Letztendlich neigen wir alle dazu, es mit Zahnspangen idiotensicher zu machen ... weil, na ja, wissen Sie.


3
das wird besonders lesbar sein, wenn ein unschuldiger Betreuer else while(...) bar();etwas ändert wie else while(...) foobar(); bar();:)
Mücke

3
Nun, ich würde sagen, das ist ein ziemlich dummer und gefährlicher unschuldiger Betreuer. Ich kenne das Prinzip, es herunterzudrehen, um dumme Fehler zu vermeiden ... aber es ist trotzdem ziemlich traurig, so weit zu gehen. Aber ich wusste, dass ich solche Kommentare und Ablehnungen bekommen würde. Kein Problem.
dagnelies

2
"Codieren Sie immer so, als ob die Person, die Ihren Code verwaltet, ein gewalttätiger Psychopath ist, der weiß, wo Sie leben." ( Alan Braggins )
Mücke

1
Nun, alles läuft auf das hinaus, von dem Sie annehmen, dass es das dümmste Niveau von jemandem ist, der an Ihrem Code arbeitet. Ich behaupte, wenn Ihr "Betreuer" durch diese vier Codezeilen verwirrt wird ... dann haben Sie ein massives Problem in der Hand. Und wenn es ein gewalttätiger Psycho ist, hast du zwei. ;)
dagnelies

1
if - Nun, der Link, auf den ich oben verweise, hat die Version dieses Zitats erweitert: Programmer 1: 'Hier gibt es ein nettes Zitat - "Codiere immer so, als ob die Person, die deinen Code verwaltet, ein gewalttätiger Psychopath ist, der weiß, wo du lebst." . Programmierer 2: (schaut zum Betreuer) 'Was meinst du mit "als ob"?'
Mücke

2

Ich setze immer geschweifte Klammern ein, nur weil Sie in Eile möglicherweise eine weitere Zeile einfügen, sie einrücken, die geschweiften Klammern vergessen und sich am Kopf kratzen, was gerade passiert. Ich halte die öffnende Klammer in der gleichen Zeile, aber es spielt keine Rolle. In beiden Fällen ist es besser, sie zu haben.

if(blah) {
    foo();
}
else {
    bar();
}

Das Positionieren von Klammern löst wahrscheinlich mehr Argumente aus als alles, was über die Religion hinausgeht (oder möglicherweise die Religion einschließt)!
Andrew

Einverstanden. Ich bearbeite meine Antwort, um ihre Existenz und nicht ihre Position hervorzuheben.
Tsvetomir Dimitrov

2

Was ist so falsch an geschweiften Klammern, dass so viele Menschen versuchen, es zu vermeiden, sie zu schreiben?

Welches Problem löst genau else while?

Zahnspangen sind billig und gut, und sie machen die Code-Intention klar und deutlich im Gegensatz zu clever und witzig.

Zitieren der Unix-Philosophie:

Regel der Klarheit: Klarheit ist besser als Klugheit.

Da Wartung so wichtig und so teuer ist, schreiben Sie Programme so, als ob die wichtigste Kommunikation nicht an den Computer gerichtet wäre, auf dem sie ausgeführt werden, sondern an die Menschen, die den Quellcode in Zukunft lesen und pflegen werden (einschließlich Sie selbst).


1

Es ist nichts falsch daran

if (blah)
    foo();
else
    bar();

als wäre nichts falsch daran

if (blah) foo(); else bar();

unter den richtigen Umständen (Ihre Umstände können variieren, aber dieser bestimmte Stil wird am besten verwendet, wenn Sie viel sich wiederholenden Code haben - dann ist die Ansicht jeder Zeile wichtiger als der stilistische Einzug)

Aber wenn Sie einen Weg wählen, bleiben Sie dabei - Konsistenz ist König. Ihr zweites Beispiel ist also sehr schlecht, da der if-Ausdruck eckige Klammern für seine Anweisung enthält und die while-Anweisung nicht außerhalb, sondern innerhalb der eckigen Klammern für die else-Klausel stehen sollte.


außerdem habe ich diesen Code schon mal gesehen:

if (x) foo()
{
  bar();
}

und es wurde von der Kodierungsnorm nazi selbst geschrieben (der für alles auf Klammern bestand).


1

Moderne IDEs können einfach so konfiguriert werden, dass sie neu formatieren (einschließlich Entfernen oder Hinzufügen unnötiger Klammern) und / oder den Code beim Speichern einer Datei erneut einblenden. So würde Ihr Beispiel zum Beispiel automatisch aussehen

if (blah) {
  blub();
} else
  while (!bloop()) {
    bar();
  }

Durch die Einkerbung ist die Verschachtelung auch ohne unnötige Klammern immer gut sichtbar. Wenn Sie es also schaffen, solche IDE-Einstellungen durchzusetzen, sehe ich kein Risiko.

Persönlich finde ich Code, der die geschweiften Klammern und Zeilenumbrüche weglässt, viel lesbarer, da er Unordnung vermeidet:

if (blah) blub();
else while (!bloop()) bar();

Aber natürlich streiten sich viele Entwickler sehr gerne für immer und einen Tag über solche Dinge.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.