2009-05-19 6 views
5

Duplizieren:Should a function have only one return statement?Bessere Java-Methode Syntax? Früh oder spät zurückkehren?

Oft Sie vielleicht eine Methode, die zahlreiche Bedingungen überprüft und gibt einen Status (boolean sagen jetzt lässt). Ist es besser, eine Flagge zu definieren, setzen Sie ihn während des Verfahrens, und senden Sie es am Ende:

boolean validate(DomainObject o) { 
    boolean valid = false; 
    if (o.property == x) { 
    valid = true; 
    } else if (o.property2 == y) { 
    valid = true; 
    } ... 
    return valid; 
} 

oder ist es besser/richtigere einfach zurück, sobald Sie die Methode der Ergebnisse wissen?

boolean validate(DomainObject o) { 

    if (o.property == x) { 
    return true; 
    } else if (o.property2 == y) { 
    return true; 
    } ... 
    return false; 
} 

Jetzt könnte es offensichtlich versuchen/fangen Blöcke und alle anderen Arten von Bedingungen, aber ich denke, das Konzept ist klar. Meinungen?

+0

Nur eine Eigenschaft muss gültig sein, damit das Ganze gültig ist? –

+0

duplizieren http://stackoverflow.com/questions/36707/should-a-function-have-only-one-return-statement –

+0

ein anderer Link http://stackoverflow.com/questions/124122/single-return-or- multiple-return-statements-closed –

Antwort

7

Wenn es eine Methode ist, die Sie Tausende Male anrufen werden, dann ist frühzeitige Rückkehr besser, um eine [etwas] erhöhte Leistung zu erreichen.

Wenn nicht, dann würde ich eine späte Rückgabe bevorzugen, da es die Lesbarkeit verbessert.

Denken Sie daran, dass Programmierer in der Regel mehr Zeit mit Lesen verbringen als mit dem Schreiben von Code. Daher ist alles, was Sie tun können, um die Lesbarkeit zu verbessern, sicherlich willkommen.

+21

Wie ist die späte Rückgabe lesbarer? Für mich ist es kompliziert, zu spät zu kommen. Ich folge daraus, dass die Methode nicht ausgeführt wird, wenn sie nicht zurückgekehrt ist. –

+0

Es ist besser lesbar, weil Sie den Prozess nicht in der Mitte schneiden. Stattdessen speichern Sie den Status und kehren am Ende der Methode zurück. – Seb

+7

Ich finde die Flagge viel weniger lesbar, weil Sie genau jeder Bedingung, Methodenaufruf usw. folgen müssen, um zu wissen, ob jemand anderes die Flagge vor der Rückkehr berührt hat, während Sie mit der anderen Alternative sicher sind, dass die Eigenschaft gleich x ist wird wahr werden, egal was sonst dort passiert. –

1

Für mich ist das eine Art von diesen religiösen Kriegsthemen mit keiner richtigen Antwort. Das Argument gegen eine frühe Rückkehr läuft im Wesentlichen darauf hinaus, dass die Anzahl der möglichen Pfade durch den Code, die theoretisch nur einen Punkt enthält, wo eine Funktion austreten kann, reduziert wird, was zumindest theoretisch die Fehlerwahrscheinlichkeit verringert. Mein persönlicher Stil ist es, in Situationen, in denen es Sinn macht, früh zurückzukehren, und in Situationen, in denen es Sinn macht, auf eine Rückmeldung zu verzichten, dies zu tun.

0

Persönlich mag ich die zweite Methode besser. Es ist für mich einfacher und klarer, aber ich weiß, dass es Leute gibt, die nur eine einzige Rückkehr in einer Funktion haben müssen.

5

Wie bei den meisten Codierungsstilen ist es wirklich eine Frage der Präferenz, aber guard clauses werden von vielen als eine Best Practice angesehen.

+0

Dies ist keine Frage der Wächterklausel; Es kommt darauf an, abhängig von Parametern unterschiedliche Werte zurückzugeben. Niemand sprach davon, dass Parameter richtig oder falsch sind oder dass Vorbedingungen erforderlich sind. – Seb

+0

@Seb: Guard-Klauseln sind ähnlich, nicht die gleichen wie Vorbedingungen.Guard-Klauseln sind auch nicht auf die Parametervalidierung beschränkt. Sie können eine Guard-Klausel verwenden, um in trivialen Fällen schnell zurückzukehren, was zu mehreren Rückgabepunkten führt. Genau darum geht es in der Frage. –

1

Wenn Ausnahmen nicht Teil des Bildes sind, ziehe ich es vor, sofort zurückzukehren, wenn ich kann.

Es kann leicht sein, die Flag-Variable falsch zu verwalten und ich bin gegen Flag-Variablen im Allgemeinen. Wenn Sie nicht zurückkommen, könnte ein Betreuer denken, dass weitere Arbeit geleistet werden könnte (wenn die Methode lang ist).

0

Ehrlich gesagt denke ich, es hängt von der Situation ab. Persönlich benutze ich beide, und ich entscheide, basierend auf welcher wird den Code klarer und einfacher zu lesen.

Wenn Sie stark verschachtelte if-Anweisungen (oder irgendeine andere Steuerstruktur) und es kann verwirrend sein, dann würde ich in den Anweisungen geben

Sie nicht zu viel Sorgen darüber, was ‚best practice‘ in dieser Fall, da es wichtiger ist, dass der Code klar und einfach zu verstehen ist. Verwenden Sie, was sich für die Situation richtig anfühlt.

8

Ich ziehe es vor, früh zurückzukehren und tiefe Verschachtelung zu vermeiden. Dies ist insbesondere wahr gleich zu Beginn der Methode: Testen Sie alles, was einfach ist, und raus (oder werfen Sie eine Ausnahme), wenn Sie dies wirklich früh tun können.

Wenn es mitten in einer Methode ist, ist es eher ein Urteilsspruch.

Bitte beachte, dass ich Ihr Beispiel Refactoring würde sofort eine einzige verwenden if:

boolean validate(DomainObject o) {  
    if (o.property == x || o.property2 == y) { 
    return true; 
    } ... 
    return false; 
} 

Ich weiß, das nur ein Spielzeug Beispiel war, aber mein Punkt ist, dass es immer lohnt, für mehr Möglichkeiten suchen, zu vereinfachen Ihr Code :)

0

Für diesen Fall ziehe ich:

boolean validate (DomainObject o) { 
    if (o.property == x || 
     o.property2 == y || 
     ...) { 
      return true; 
    } else { 
      return false; 
} 

Im allgemeinen ich mag frühe Rückkehr verwenden, um Fehlerbedingungen zu behandeln und Rückkehr am Ende um berechnete Ergebnisse zurückzugeben.

0

Es gibt zwei Faktoren, die sich gegenseitig beeinflussen.

Der erste Faktor ist die einfache Fehlersuche. Wenn Sie sofort zurückkehren (wie in Ihrem zweiten Code-Snippet gezeigt), wird es manchmal schwierig, eine große Funktion zu debuggen, da es schwierig ist, diese Return-Anweisungen zu finden, besonders wenn sie versehentlich dort abgelegt wurden.

Der zweite Faktor ist die einfache Implementierung. Wenn Sie die grundlegende Korrektheit von Argumenten zu Beginn der Funktion überprüfen und es vor dem Ende der Funktion einen langen Codeabschnitt gibt, müssen Sie möglicherweise den gesamten Code in eine Bedingungsschleife einfügen. Wenn Sie das nicht tun, könnte das Argument irgendwann für eine lange Berechnung verwendet werden, was Zeitverschwendung wäre, weil es letztendlich sowieso abgelehnt würde.

So könnte die Antwort so aussehen:

If the function is small, 
     save the return status in a variable and return at the end. 
else 
     return immediately. 
4

Das einzige Mal, wenn ich Sie auf jeden Fall zurückkehren sollte nicht zu früh sagen kann, ist, wenn man nicht so leicht jede Rückkehr in einem einzigen Bildschirm sehen können (was auch immer das Standard könnte für Leute sein, die an der gleichen Code-Basis arbeiten), sollten Sie zumindest Kommentare hinzufügen, die anzeigen, dass die Funktion früh zurückkehren kann, wenn es eine vorzeitige Rückgabe gibt.

Das einzige Mal, dass ich sollte auf jeden Fall früh sagen würde zurückkehren, wenn Ihr Code wie folgt aussieht ...

boolean valid = true; 
if(condition1) { 
    valid = false; 
} 
if(valid) { 
    ... 
    if(condition2) { 
     valid = false; 
    } 
} 
if(valid) { 
    ... 
    if(condition3) { 
     valid = false; 
    } 
} 
... (etc) 

Wenn Sie sich in beiden Situationen finden, aber ... Sie wahrscheinlich Refactoring sein sollte die Funktion.

+0

+1 für Ihre letzte Zeile; Sie sollten in der Tat kleinere Methoden herausziehen, wenn die Funktion zu lang wird. – Hace