Frage

Dies ist eine kleine Stil Frage, aber jedes Stück Lesbarkeit fügen Sie Ihren Code zählt.

Also, wenn Sie haben:

if (condition) then
{
   // do stuff
}
else
{
   // do other stuff
}

Wie kann man entscheiden, ob es so besser ist, oder wie folgt aus:

   if (!condition) then
   {
     // do other stuff
   {
   else
   {
     // do stuff
   }

Meine Heuristiken sind:

  1. Halten Sie den Zustand positiv (weniger Kopfrechnen beim Lesen)
  2. Legen Sie die gängigste Weg in die erster Block
War es hilfreich?

Lösung

Ich ziehe die häufigste Weg zuerst zu setzen, und ich bin ein überzeugter Anhänger Verschachtelung Reduktion also werde ich brechen, continue oder zurückgeben statt Elsing, wann immer möglich. Ich ziehe es generell gegen positive Bedingungen zu testen, oder Invertzucker [und Namen] negative Bedingungen als positiv.

if (condition)
    return;

DoSomething();

Ich habe, dass mein Code durch eine drastische Reduzierung die Verwendung von anderen gefunden besser lesbar und wartbar ist und wenn ich seinen habe anderes verwenden fast immer einen ausgezeichneten Kandidaten für eine strukturierteren switch-Anweisung.

Andere Tipps

Zwei (widersprüchlichen) Lehrbuch zitiert:

  

Setzen Sie die kürzeste Klausel einer if / else   auf

- Alle Holub, "Enough Rope schießen sie in dem Fuß", p52

  

Setzen Sie den Normalfall nach dem, wenn nicht nach dem sonst

- Steve McConnell "Code Complete, 2nd ed", P356

Ich ziehe die erste. Der Zustand sollte so einfach wie möglich sein, und es sollte ziemlich offensichtlich sein, die aus Zustand und! Bedingung einfacher ist

Es hängt von Ihrem Flow. Für viele Funktionen, werde ich Voraussetzungen verwenden:

bool MyFunc(variable) {
    if (variable != something_i_want)
        return false;

    // a large block of code
    // ...
    return true;
}

Wenn ich muß tun etwas jeden Fall werde ich ein if (positive_clause) {} else {}-Format verwenden.

Wenn der Code für eine Fehlerbedingung zu prüfen ist, ziehe ich zuerst diesen Code zu setzen, und die „erfolgreiche“ Code Sekunde; konzeptionell, hält diese einen Funktionsaufruf und seine Fehlerprüfung Code zusammen, das macht Sinn für mich, weil sie verwandt sind. Zum Beispiel:

  if (!some_function_that_could_fail())
  {
     // Error handling code
  }
  else
  {
     // Success code
  }

ich mit Oli stimmen positiv über die Verwendung, wenn Klausel, wenn möglich.

Nur bitte nie tun:

if (somePositiveCondition)
else {
    //stuff
}

habe ich diese eine Menge an einem Ort zu sehen, die mich gearbeitet und verwendet zu fragen, ob einer der Programmierer nicht verstehen, wie man es nicht funktioniert ...

Wenn ich die Datenvalidierung suchen, versuche ich meine Bedingungen „Whitelisting“ zu machen - das heißt, ich testen, was ich akzeptieren:

if DataIsGood() then
   DoMyNormalStuff
else
   TakeEvasiveAction

Anstatt umgekehrt, die in degenerieren neigt:

if SomeErrorTest then
  TakeSomeEvasiveAction
else if SomeOtherErrorCondition then
  CorrectMoreStupidUserProblems
else if YetAnotherErrorThatNoOneThoughtOf then
  DoMoreErrorHandling
else
  DoMyNormalStuff

Ich weiß, das ist nicht genau das, was Sie suchen, aber ... Viele Entwickler verwenden, um eine „Guard-Klausel“, das heißt, ein negativen „if“ Anweisung, die so schnell aus dem Verfahren bricht als möglich. An diesem Punkt gibt es keine „else“ wirklich.

Beispiel:

if (blah == false)
{
    return; // perhaps with a message
}

// do rest of code here...

Es gibt einige Hard-Core-C / C ++ / Montage Jungs da draußen, die Ihnen sagen, dass Sie Ihre CPU sind zu zerstören !!! (In vielen Fällen Prozessoren bevorzugen die „wahre“ Aussage und versuchen, „Prefetch“ das nächste, was zu tun ... so theoretisch jeder „false“ Zustand wird das Rohr spülen und geht Mikrosekunden langsamer).

Meiner Meinung nach sind wir an dem Punkt, wo „besser“ (verständlicher) Code siegt über Mikrosekunden CPU-Zeit.

Ich denke, für eine einzelne Variable, dass das nicht Bediener einfach genug ist und die Benennung Probleme beginnen, mehr relevant zu sein.

Name nie eine Variable not_X, wenn in der Notwendigkeit einen Thesaurus verwenden und eine entgegengesetzte finden. Ich habe viele schrecklichen Code gesehen wie

if (not_dead) {
} else {
}

anstelle der offensichtlichen

if (alive) {
} else {
}

Dann können Sie sanely verwenden (sehr gut lesbar, keine Notwendigkeit, die Codeblöcke zu invertieren)

if (!alive) {
} else {
}

Wenn wir über mehr Variablen sprechen Ich denke, die beste Regel ist die Bedingung zu vereinfachen. Nach einer gewissen Zeit neigen Projekte Bedingungen erhalten wie:

if (dead || (!dead && sleeping)) {
} else {
}

Welche übersetzt

if (dead || sleeping) {
} else {
}

immer darauf achten, welche Bedingungen aussehen und wie sie zu vereinfachen.

Software ist die Wissenserfassung. Sie kodieren jemandes Wissen, wie etwas zu tun.

Die Software sollte passen, was für das Problem „natürlich“ ist. Wenn Sie Zweifel haben, fragen Sie jemand anderen und sehen, was die Leute sagen, tatsächlich und tun.

Was ist mit der Situation, in der der „gemeinsame“ Fall nichts tun? Was dann

if( common ) {
    // pass
}
else {
    // great big block of exception-handling folderol
}

Oder tun Sie das?

if( ! common ) {
    // great big block of except-handling folderol
}

Die „immer positiv“ Regel ist nicht wirklich das, was Sie wollen zuerst. Sie wollen an Regeln aussehen wie folgt aus.

  1. Immer natürlich - es sollte wie Englisch lesen (. Oder was auch immer die gemeinsame Sprache in Ihrer Organisation ist)
  2. Wo es möglich ist, gemeinsame Fälle zuerst - so erscheinen sie häufig
  3. .
  4. Wo es möglich ist die Verwendung positive Logik; negative Logik kann verwendet werden, wo es häufig gesagt, dass die Art und Weise oder in denen der gemeinsamen Fall ist ein do-nothing.

Wenn einer der beiden Wege sehr kurz ist (1 bis 10 Zeilen oder so) und das andere ist viel länger, ich folge der Holub Regel erwähnte hier und legt das kürzere Stück Code in der if. Das macht es leichter, die if / else Fluss auf einem Bildschirm zu sehen, wenn Sie den Code zu überprüfen.

Wenn das nicht möglich ist, dann strukturiere ich die Bedingung so einfach wie möglich zu machen.

Für mich ist es unter der Bedingung abhängig, zum Beispiel:

if (!PreserveData.Checked)
{  resetfields();}

Ich neige dazu, mich selbst zu sprechen mit dem, was ich der Logik möchte die kleine Stimme in meinem Kopf sein und Code es.

Sie können in der Regel die Bedingung positiv machen, ohne um die if / else Blöcke umgeschaltet wird.

Ändern

   if (!widget.enabled()) {
     // more common 
   } else {
     // less common 
   }

   if (widget.disabled()) {
     // more common 
   } else {
     // less common
   }

Intel Pentium Verzweigungsvorhersage vorge holt Anweisungen für die „if“ Fall. Wenn es stattdessen den „else“ Zweig folgt: Es hat die bündig die Befehls-Pipeline, einen Stall zu verursachen.

Wenn Sie viel über die Leistung kümmern. Legt das wahrscheinlichste Ergebnis in der ‚if‘ Klausel

Persönlich schreibe ich es als

if (expected)
{
   //expected path
}
else
{
   //fallback other odd case
} 

Wenn Sie beide wahr und falsch Bedingungen haben, dann würde ich für eine positive bedingte entscheiden -. Dies reduziert Verwirrung und im Allgemeinen Ich glaube, Ihr Code leichter macht zu lesen

Auf der anderen Seite, wenn Sie eine Sprache wie Perl verwenden, und vor allem, wenn Ihr falscher Zustand ist entweder ein Fehler oder die häufigste Bedingung, können Sie mit dem ‚es sei denn‘ Struktur, die den Codeblock führt es sei denn, die Bedingung erfüllt ist (dh das Gegenteil von if):

unless ($foo) {
    $bar;
}

Zunächst einmal wollen wir Situationen zur Seite legen, wenn es besser ist, mit „else“ in erster Linie zu vermeiden (ich hoffe, alle sind sich einig, dass solche Situationen existieren und solche Fälle zu bestimmen sollte wohl ein anderes Thema sein).

Also, nehmen wir an, es müsse eine "else" Klausel sein.

Ich denke, dass die Lesbarkeit / Verständlichkeit mindestens drei wichtigsten Anforderungen oder Regeln auferlegt, die leider oft miteinander konkurrieren:

  1. Je kürzer ist der erste Block (der „if“ Block), desto leichter ist es die gesamte „if-else“ konstruieren zu erreichen. Wenn die „if“ Block lang genug ist, ist es viel zu einfach wird Existenz von „else“ Block zu übersehen.

  2. Wenn die "if" und "else" Pfade sind logisch asymmetrisch (zB "normale Verarbeitung" vs. "Fehlerverarbeitung"), in einem Standalone "if-else" konstruiert es Materie viel nicht wirklich, welcher Weg zuerst ist und welche zweite. Allerdings, wenn es mehr „if-else“ Konstrukte in Nähe zueinander (einschließlich Verschachtelung), und wenn alle dieser „if-else“ Konstrukte Asymmetrie der gleichen Art haben - das ist, wenn es sehr wichtig, konsequent diese asymmetrischen Pfade zu arrangieren.

    Auch hier kann es „wenn ... Normalweg ... else ... abnormal Weg“ sein für alle, oder „wenn ... abnormal Weg ... else ... normalen Weg“ für alle, aber es soll nicht eine Mischung aus diesen beiden Varianten sein.

    Bei allen anderen Bedingungen gleich sind, zuerst den normalen Weg zu bahn ist wahrscheinlich natürlicher für die meisten Menschen (ich glaube, es ist mehr über Psychologie als Ästhetik: -).

  3. Ein Ausdruck, der in der Regel mit einer Negation beginnt, ist weniger lesbar / verständlich als ein Ausdruck, der dies nicht tut.

So haben wir diese drei konkurrierenden Anforderungen / Regeln, und die eigentliche Frage ist: welche von ihnen wichtiger sind als andere. Für Allen Holub die Regel # 1 ist wahrscheinlich der wichtigste. Für Steve McConnell - es ist die Regel # 2. Aber ich glaube nicht, dass Sie wirklich nur eine dieser Regeln als ein einziger quideline wählen können.

ich wette, du hast schon hier meine persönlichen Prioritäten erraten (von der Art, wie ich oben :-) die Regeln bestellt.

Meine Gründe sind einfach:

  • Die Regel # 1 ist bedingungslos und unmöglich zu umgehen. Wenn einer der Blöcke so lange ist, dass es aus dem Bildschirm läuft - es muss die „else“ -Block werden. (Nein, es ist keine gute Idee, eine Funktion / Methode mechanisch zu erstellen, die Anzahl der Zeilen in einer „if“ oder „else“ -Block zu verringern! Ich gehe davon aus, dass jeder Block bereits eine hat logisch vertretbar Minimum an Linien).

  • Die Regel # 2 beinhaltet eine Menge von Bedingungen: mehrere „if-else“ Konstrukte, die alle mit Asymmetrie der gleichen Art, etc. Also es funktioniert einfach nicht in vielen Fällen anwenden.

    Auch ich oft folgendes interessantes Phänomen beobachten: wenn die Regel # 2 gelte, und wenn es richtig eingesetzt wird, ist es eigentlich nicht mit der Regel # 1 in Konflikt! Zum Beispiel, wenn ich eine Reihe von „if-else“ Anweisungen mit „normalen vs. abnormal“ Asymmetrie haben, werden alle „abnormal“ Wege sind kürzer als „normale“ Einsen (oder umgekehrt). Ich kann dieses Phänomen nicht erklären, aber ich denke, dass es nur ein Zeichen der guten Code Organisation ist. Mit anderen Worten, wenn ich eine Situation sehen, wenn Regeln # 1 und # 2 in Konflikt ist, fange ich an der Suche nach „Code Smells“ und mehr als oft nicht, dass ich einige tun finden; und nach dem Refactoring - tada! keine schmerzhafte Wahl zwischen Regel # 1 und Regel # 2, :-)

  • Schließlich 3 die Regel # hase den kleinsten Umfang und daher ist die am wenigsten kritisch.

    Auch, wie hier von anderen Kollegen mentined, ist es oft sehr einfach zu „betrügen“ mit dieser Regel (zum Beispiel zu schreiben „wenn (deaktiviert) ,,,“ anstelle von „if (! Enabled) ... „).

Ich hoffe, dass jemand ein Gefühl für dieses Werk machen kann ...

Als allgemeine Regel gilt, wenn man deutlich größer als der andere ist, ich mache die größeren den if Block.

  1. legt den gemeinsamen Weg zuerst
  2. drehen negativ cheking in positive (!full == empty)

Ich habe immer die höchstwahrscheinlich zuerst.

In Perl hat er eine zusätzliche Kontrollstruktur mit dem helfen. Die Inverse wenn.

unless (alive) {
     go_to_heaven;
} else {
     say "MEDIC";
}

Sie sollten immer an erster Stelle die wahrscheinlichste Fall. Neben mehr lesbar ist, ist es schneller. Dies gilt auch Aussagen zu wechseln.

Ich bin schrecklich, wenn es darum geht, wie ich, wenn Aussagen aufgebaut. Im Grunde habe ich es einrichten auf, was genau ich suche, was dazu führt, alles anders zu sein.

if (userinput = null) {
   explodeViolently ();
} Else {
tatsächlich tun Sachen;
}

oder vielleicht so etwas wie

wenn (1 + 1 = 2) {
tun Sachen;
} Else {
explodeViolently ();
}

Welcher Abschnitt der if / else-Anweisung tatsächlich tut Dinge für mich ist eine schlechte Angewohnheit von mir.

Ich habe im Allgemeinen das positive Ergebnis (so dass die Methode) am Anfang so:

if(condition)
{
doSomething();
}
else
{
System.out.println("condition not true")
}

Aber wenn die Bedingung falsch sein muss für das Verfahren verwendet wird, würde ich dies tun:

if(!condition)
{
doSomething();
}
else
{
System.out.println("condition true");
}

Wenn Sie mehrere Austrittspunkte haben müssen, stellen sie erste und machen sie klar:

if TerminatingCondition1 then
  Exit
if TerminatingCondition2 then
  Exit

Jetzt können wir mit dem üblichen Sachen Fortschritt:

if NormalThing then
  DoNormalThing
else
  DoAbnormalThing
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top