Ist die vorzeitige Rückkehr von einer Funktion eleganter als eine if-Anweisung?

StackOverflow https://stackoverflow.com/questions/355670

  •  21-08-2019
  •  | 
  •  

Frage

Ich und ein Kollege streiten darüber, welche der folgenden Lösungen eleganter ist.Ich werde nicht sagen, wer wer ist, daher ist es unparteiisch.Was ist eleganter?

public function set hitZone(target:DisplayObject):void
        {
            if(_hitZone != target)
            {
                _hitZone.removeEventListener(MouseEvent.ROLL_OVER, onBtOver);
                _hitZone.removeEventListener(MouseEvent.ROLL_OUT, onBtOut);
                _hitZone.removeEventListener(MouseEvent.MOUSE_DOWN, onBtDown);

                _hitZone = target;

                _hitZone.addEventListener(MouseEvent.ROLL_OVER, onBtOver, false, 0, true);
                _hitZone.addEventListener(MouseEvent.ROLL_OUT, onBtOut, false, 0, true);
                _hitZone.addEventListener(MouseEvent.MOUSE_DOWN, onBtDown, false, 0, true);
            }
        }

...oder...

public function set hitZone(target:DisplayObject):void
        {
            if(_hitZone == target)return;

            _hitZone.removeEventListener(MouseEvent.ROLL_OVER, onBtOver);
            _hitZone.removeEventListener(MouseEvent.ROLL_OUT, onBtOut);
            _hitZone.removeEventListener(MouseEvent.MOUSE_DOWN, onBtDown);

            _hitZone = target;

            _hitZone.addEventListener(MouseEvent.ROLL_OVER, onBtOver, false, 0, true);
            _hitZone.addEventListener(MouseEvent.ROLL_OUT, onBtOut, false, 0, true);
            _hitZone.addEventListener(MouseEvent.MOUSE_DOWN, onBtDown, false, 0, true);

        }
War es hilfreich?

Lösung

Dies ist einer der Fälle, wo es ist in Ordnung, die Regeln zu brechen (das heißt Best Practices). In der Regel wollen Sie als wenige Rückkehrpunkte in einer Funktion wie möglich haben. Der praktische Grund dafür ist, dass es beim Lesen des Codes vereinfacht, da man nur immer kann seine Logik davon ausgehen, dass jeder und jede Funktion ihre Argumente nehmen, tun, und das Ergebnis zurück. Nachlegen Renditen für verschiedene Fälle tendiert dazu, die Logik und erhöht die Menge der Zeit, die notwendig zu lesen und voll grok den Code zu erschweren. Sobald Sie den Code der Wartungsstufe dann mehrere Renditen erreicht einen enormen Einfluss auf die Produktivität der neuen Programmierer haben können, wie sie versuchen, die Logik zu entschlüsseln (seine besonders schlecht, wenn Kommentare sind spärlich und der Code unklar). Das Problem wächst exponentiell mit Bezug auf die Länge der Funktion.

Also, warum in diesem Fall ist es vorziehen, jede Option 2? Es ist, weil Sie werden einen Vertrag einrichten, der die Funktion erzwingt durch eingehende Daten Validierung oder andere Invarianten, die überprüft werden können müssen. Die hübscheste Syntax für die Validierung der Konstruktion ist die Überprüfung jeden Zustand, die Rückkehr sofort, wenn die Bedingung Gültigkeit versagt. Auf diese Weise müssen Sie nicht irgendeine Art von isValid boolean durch alle Ihre Schecks erhalten.

Um die Dinge zusammenzufassen: wir wirklich schauen, wie Validierungscode zu schreiben und nicht allgemeine Logik; Option 2 ist besser für den Validierungscode.

Andere Tipps

In den meisten Fällen frühe Rückkehr reduziert die Komplexität und macht den Code besser lesbar.

Es ist auch eine der in Spartan Programmierung :

  

Minimaler Einsatz von Kontrolle

     
      
  1. Die Minimierung der Verwendung von conditionals durch spezialisierte Verwendung   Konstrukte wie beispiels ternarization,   Vererbung und Klassen wie Klasse   Defaults, Klasse Einmal und Klasse   Separator
  2.   
  3. Vereinfachen conditionals mit frühem return.
  4.   
  5. Die Minimierung der Verwendung von Schleifenkonstrukte, durch Aktion Applikator   Klassen wie Klasse Separate und   Klasse FileSystemVisitor.
  6.   
  7. Vereinfachen Logik der Iteration mit frühen Exits (via return,   continue und break Aussagen).
  8.   

In Ihrem Beispiel würde ich wählen Sie Option 2, da sie den Code besser lesbar macht. Ich benutze die gleiche Technik, wenn Funktionsparameter zu überprüfen.

Solange die frühen kehrt als Block an der Spitze der Funktion / Methode Körper organisiert sind, dann denke ich, sie sind viel besser lesbar als eine weitere Ebene der Verschachtelung hinzugefügt wird.

Ich versuche, frühe Rückkehr in der Mitte des Körpers zu vermeiden. Manchmal sind sie der beste Weg, aber die meiste Zeit denke ich, sie erschweren.

Auch als allgemeine Regel versuche ich Verschachtelung Kontrollstrukturen zu minimieren. Natürlich können Sie diese ein zu weit, so müssen Sie einen Ermessensspielraum nutzen. Konvertieren von verschachtelten, wenn die auf einen einzelnen Schalter / Fall viel klarer zu mir, auch wenn die Prädikaten einiger Unterausdrücke wiederholen (und dies unter der Annahme, ist keine leistungskritische Schleife in einer Sprache zu dumm subexpression Beseitigung zu tun). Besonders mag ich die Kombination von verschachtelten ifs in langen Funktion / Methode Körper, denn wenn man in der Mitte aus irgendeinem Grund des Codes springen Sie Scrollen am Ende nach oben und unten mental den Kontext einer bestimmten Linie zu rekonstruieren.

Meiner Erfahrung nach besteht das Problem bei der Verwendung früher Renditen in einem Projekt darin, dass andere Projektbeteiligte nicht danach suchen, wenn sie nicht daran gewöhnt sind.Wenn also mehrere Programmierer beteiligt sind, stellen Sie sicher, dass sich zumindest jeder über ihre Anwesenheit im Klaren ist.

Ich persönlich schreibe Code, der so schnell wie möglich zurückkommt, da die Verzögerung einer Rückkehr oft zusätzliche Komplexität mit sich bringt, z. B. der Versuch, eine Reihe verschachtelter Schleifen und Bedingungen sicher zu verlassen.

Wenn ich mir also eine unbekannte Funktion ansehe, suche ich als Erstes nach all dem returnS.Was dort wirklich hilft, ist, die Syntaxfarbe so einzurichten, dass sie gegeben ist return eine andere Farbe als alles andere.(Ich wähle Rot.) Auf diese Weise ist das returns werden zu einem nützlichen Werkzeug, um zu bestimmen, was die Funktion tut, anstatt zu versteckten Stolpersteinen für Unvorsichtige.

Ah der Wächter.

Imho, ja - die Logik ist es klarer, weil die Rückkehr explizit ist und direkt neben den Zustand, und es kann gut mit ähnlichen Strukturen gruppiert werden. Dies gilt umso mehr gelten, wenn „return“ mit „throw new Exception“ ersetzt wird.

sagte nach wie vor frühe Rückkehr ist besser lesbar, besonders, wenn der Körper einer Funktion lang ist, können Sie feststellen, dass ein Löschen} versehentlich in einer 3-Seiten-Funktion (Weicht an sich nicht sehr elegant ist) und zu versuchen, zu kompilieren es kann einige Minuten von nicht-automatisierbare Debuggen nehmen.

Es macht auch der Code deklarative, denn das ist der Weg Sie sie zu einem anderen Menschen beschreiben würden, so wahrscheinlich ein Entwickler ist nahe genug, um eine, es zu verstehen.

Wenn die Komplexität der Funktion erhöht sich später, und Sie gute Tests haben, können Sie einfach jede Alternative in einer neuen Funktion wickeln, und nennen sie bei Filialen, da man so die deklarative Stil mantain.

In diesem Fall (ein Test, keine else-Klausel) Ich mag die Test-and-Return. Es macht deutlich, dass in diesem Fall gibt es nichts zu tun, ohne dass der Rest der Funktion zu lesen.

Dies ist jedoch spaltet die feinsten Haare. Ich bin sicher, Sie müssen größere Probleme zu befürchten:)

Option 2 ist besser lesbar, aber die Handhabbarkeit des Code schlägt fehl, wenn ein anderes erforderlich sein kann, hinzugefügt werden.

Also, wenn Sie sicher sind, gibt es keine andere für Option gehen 2, aber wenn es Spielraum für eine andere Bedingung sein könnte, dann würde ich es vorziehen, die Option 1

Option 1 ist besser, weil Sie eine minimale Anzahl von Rückkehrpunkten in Verfahren haben sollten. Es gibt Ausnahmen wie

  if (a) {
    return x;
  }
  return y;

wegen der Art, eine Sprache funktioniert, aber im Allgemeinen ist es besser als wenige Ausstiegspunkte zu haben, wie es machbar ist.

Ich ziehe eine sofortige Rückkehr zu Beginn einer Funktion zu vermeiden, und, wann immer möglich, die Qualifikationslogik setzt Eintritt in das Verfahren zu verhindern, bevor es aufgerufen wird. Natürlich variiert je nach Zweck des Verfahrens.

Allerdings habe ich nichts dagegen, in der Mitte des Verfahrens zurückkehrt, sofern das Verfahren kurz und lesbar ist. Für den Fall, dass das Verfahren groß ist, meiner Meinung nach, ist es schon nicht sehr gut lesbar, so wird es entweder in mehrere Funktionen mit Inline kehrt Refactoring, oder ich werde von der Steuerstruktur mit einer einzigen Rückkehr am Ende ausdrücklich brechen.

Ich bin versucht, es als exaktes Duplikat zu schließen, da ich einige ähnlichen Themen schon gesehen, darunter Invert‚if‘Anweisung zu reduzieren , die hat gute Antworten nisten.

Ich lasse es jetzt leben ... ^ _ ^

Damit, dass eine Antwort, ich bin ein Gläubiger, die frühe Rückkehr als Schutzklausel ist besser als tief verschachtelt ifs.

Ich habe beiden Arten von Codes gesehen, und ich ziehe erste als es für mich leicht lesbar und verständlich aussieht, aber ich habe viele Plätze gelesen, die früh existieren ist der bessere Weg zu gehen.

Es gibt mindestens eine andere Alternative. Trennen Sie die Details der tatsächlichen Arbeit von der Entscheidung darüber, ob die Arbeit zu verrichten. Etwas wie folgt aus:

public function setHitZone(target:DisplayObject):void
    {
        if(_hitZone != target)
            setHitZoneUnconditionally(target);

    }

public function setHitZoneUnconditionally(target:DisplayObject):void
    {
        _hitZone.removeEventListener(MouseEvent.ROLL_OVER, onBtOver);
        _hitZone.removeEventListener(MouseEvent.ROLL_OUT, onBtOut);
        _hitZone.removeEventListener(MouseEvent.MOUSE_DOWN, onBtDown);

        _hitZone = target;

        _hitZone.addEventListener(MouseEvent.ROLL_OVER, onBtOver, false, 0, true);
        _hitZone.addEventListener(MouseEvent.ROLL_OUT, onBtOut, false, 0, true);
        _hitZone.addEventListener(MouseEvent.MOUSE_DOWN, onBtDown, false, 0, true);

    }

Jede dieser drei (Ihre zwei plus der dritten oben) sind angemessen für Fälle so klein wie diese. Allerdings wäre es eine schlechte Sache sein, eine Funktion Hunderte von Zeilen lang mit mehreren „bail-out-Punkte“ gänzlich besprüht zu haben.

Ich habe diese Debatte mit meinem eigenen Code im Laufe der Jahre hat. Ich begann das Leben eine Rückkehr zu begünstigen und langsam verfallen.

In diesem Fall ziehe ich die Option 2 (eine Rückkehr), nur weil wir nur etwa 7 Zeilen Code durch ein if () ohne andere Komplexität gewickelt sprechen. Es ist viel besser lesbar und funktionsähnliche. Er fließt von oben nach unten. Sie wissen, dass Sie an der Spitze und am Ende am Boden beginnen.

Dass gesagt wird, wie andere gesagt haben, wenn es am Anfang oder mehr Komplexität mehr Wache waren oder wenn die Funktion wächst, dann würde ich es vorziehen Option 1:. Sofort wieder am Anfang für eine einfache Validierung

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top