Wann ist eine Funktion zu lang? [geschlossen]


130

35 Zeilen, 55 Zeilen, 100 Zeilen, 300 Zeilen? Wann sollten Sie anfangen, es auseinanderzubrechen? Ich frage, weil ich eine Funktion mit 60 Zeilen (einschließlich Kommentaren) habe und darüber nachgedacht habe, sie auseinanderzubrechen.

long_function(){ ... }

in:

small_function_1(){...}
small_function_2(){...}
small_function_3(){...}

Die Funktionen werden nicht außerhalb der Funktion long_function verwendet. Kleinere Funktionen bedeuten mehr Funktionsaufrufe usw.

Wann würden Sie eine Funktion in kleinere aufteilen? Warum?

  1. Methoden sollten nur eine logische Sache tun (über Funktionalität nachdenken)
  2. Sie sollten in der Lage sein, die Methode in einem einzigen Satz zu erklären
  3. Es sollte in die Höhe Ihres Displays passen
  4. Vermeiden Sie unnötigen Overhead (Kommentare, die auf das Offensichtliche hinweisen ...)
  5. Unit-Tests sind für kleine logische Funktionen einfacher
  6. Überprüfen Sie, ob ein Teil der Funktion von anderen Klassen oder Methoden wiederverwendet werden kann
  7. Vermeiden Sie eine übermäßige Kopplung zwischen den Klassen
  8. Vermeiden Sie tief verschachtelte Kontrollstrukturen

Vielen Dank an alle für die Antworten , bearbeite die Liste und stimme für die richtige Antwort. Ich werde diese auswählen;)

Ich überarbeite jetzt mit diesen Ideen im Hinterkopf :)


Ihre Frage enthält einen Tippfehler. Ich denke, Sie meinten "Wann ist eine Funktion zu lang?".
Tom

1
Sie geben die Frage falsch an, indem Sie sie in Codezeilen darstellen. Die Determinantenfaktoren werden nicht in Codezeilen gemessen.
dkretz

Diese Frage kann je nach Code und Sprache kompliziert werden. Vielleicht kannst du es posten.
Ray Tayek

Wenn es dem Prinzip der Einzelverantwortung entspricht, tun Sie es einfach. Normalerweise habe ich das Bedürfnis, einen Header oder alle 20 Codezeilen zu erstellen, was mich dazu veranlasst, ihn zu abstrahieren und diesem Fragment eine Funktion mit einem aussagekräftigen Namen zu geben, anstatt einen Kapitelheader zu erstellen.
Jewgenij Afanasjew

Antworten:


75

Es gibt keine wirklich festen Regeln dafür. Im Allgemeinen mag ich meine Methoden, um nur "eine Sache zu tun". Wenn es also darum geht, Daten zu erfassen, dann etwas mit diesen Daten zu tun und sie dann auf die Festplatte zu schreiben, würde ich das Erfassen und Schreiben in separate Methoden aufteilen, sodass meine "Haupt" -Methode nur das "etwas tun" enthält.

Das "etwas tun" könnte immer noch einige Zeilen umfassen, daher bin ich mir nicht sicher, ob eine Anzahl von Zeilen die richtige Metrik ist :)

Bearbeiten: Dies ist eine einzelne Codezeile, die ich letzte Woche per Post verschickt habe (um einen Punkt zu beweisen. Ich mache es mir nicht zur Gewohnheit :)) - Ich würde sicher nicht 50-60 dieser bösen Jungs in meiner Methode haben wollen : D.

return level4 != null ? GetResources().Where(r => (r.Level2 == (int)level2) && (r.Level3 == (int)level3) && (r.Level4 == (int)level4)).ToList() : level3 != null ? GetResources().Where(r => (r.Level2 == (int)level2) && (r.Level3 == (int)level3)).ToList() : level2 != null ? GetResources().Where(r => (r.Level2 == (int)level2)).ToList() : GetAllResourceList();

1
LOL Nun, ich könnte alle Leerzeichen in meiner Methode entfernen und es wäre nur eine sehr lange Zeile und keine lange Funktion. Eine Sache zu tun, das ist wahrscheinlich die Antwort als, danke

@Movaxes Das Code-Snippet, das ich gepostet habe, ist eine einzelne Anweisung, nicht nur viele Zeilen in einer Zeile. Es gibt keine Semikolons darin :) Ich hätte GetResources () jedes Mal erweitern können, um es noch böser zu machen: P.
Steven Robbins

Ja das macht Sinn. Nehmen Sie Ihre gesamte Quelldatei in eine Zeile. Ich meine, dann wirst du wirklich ein Web 2.0 "Ninja" :)
BobbyShaftoe

Ich erinnere mich, dass sie in alten Magazinen (ich spreche von BBC Micro old) früher "10-Zeilen-Programme" hatten, die nur mehrere Aussagen in jeder Zeile enthielten, bis zu der maximalen Länge, die die BBC verarbeiten konnte. Sie waren immer ein richtiger Schmerz zum Eingeben: D
Steven Robbins

6
Ich mag das Konzept, dass die Funktion nur eines tut, aber. Wenn Sie eine Funktion haben, die 10 Dinge ausführt, und 9 dieser Dinge in separate Funktionen verschieben, die immer noch von der verbleibenden Funktion aufgerufen werden, ist diese verbleibende Funktion im Wesentlichen noch 10 Dinge! Ich denke, dass das Aufteilen der Funktion auf diese Weise das Testen viel einfacher macht.
Mtnpaul

214

Hier ist eine Liste von roten Fahnen (in keiner bestimmten Reihenfolge), die darauf hinweisen könnten, dass eine Funktion zu lang ist:

  1. Tief verschachtelte Kontrollstrukturen : zB for-Schleifen 3 Ebenen tief oder sogar nur 2 Ebenen tief mit verschachtelten if-Anweisungen, die komplexe Bedingungen haben.

  2. Zu viele zustandsdefinierende Parameter : Mit zustandsdefinierendem Parameter meine ich einen Funktionsparameter, der einen bestimmten Ausführungspfad durch die Funktion garantiert. Wenn Sie zu viele dieser Parameter erhalten, kommt es zu einer kombinatorischen Explosion von Ausführungspfaden (dies geschieht normalerweise zusammen mit # 1).

  3. Logik, die bei anderen Methoden dupliziert wird : Eine schlechte Wiederverwendung von Code trägt erheblich zum monolithischen prozeduralen Code bei. Viele solcher logischen Duplikate können sehr subtil sein, aber wenn sie einmal berücksichtigt werden, kann das Endergebnis ein weitaus eleganteres Design sein.

  4. Übermäßige Kopplung zwischen Klassen : Dieses Fehlen einer ordnungsgemäßen Kapselung führt dazu, dass Funktionen sich mit intimen Merkmalen anderer Klassen befassen und diese somit verlängern.

  5. Unnötiger Overhead : Kommentare, die auf die offensichtlichen, tief verschachtelten Klassen, überflüssigen Getter und Setter für private verschachtelte Klassenvariablen und ungewöhnlich lange Funktions- / Variablennamen hinweisen, können syntaktisches Rauschen innerhalb verwandter Funktionen erzeugen, das letztendlich ihre Länge erhöht.

  6. Ihr massives Display für Entwickler ist nicht groß genug, um es anzuzeigen : Tatsächlich sind die Displays von heute groß genug, dass eine Funktion, die sich irgendwo in der Nähe ihrer Höhe befindet, wahrscheinlich viel zu lang ist. Aber wenn es größer ist , ist dies eine rauchende Waffe, bei der etwas nicht stimmt.

  7. Sie können nicht sofort die Zweck der Funktion bestimmen : Darüber hinaus , wenn Sie tatsächlich tun ihren Zweck bestimmen, wenn Sie diesen Zweck in einem einzigen Satz nicht zusammenfassen können oder passieren einen enormen Kopfschmerzen haben, soll dies ein Hinweis sein.

Zusammenfassend lässt sich sagen, dass monolithische Funktionen weitreichende Konsequenzen haben können und häufig ein Symptom für schwerwiegende Konstruktionsmängel sind. Immer wenn ich auf Code stoße , dessen Lesen eine absolute Freude ist , wird seine Eleganz sofort deutlich. Und raten Sie mal: Die Funktionen sind oft sehr kurz.


1
Netter Post! Sehr deterministisch
Chuck Conway

2
@ PedroMorteRolo Genau. Die Standard-API ist nicht immer ein Modell für Eleganz. Darüber hinaus wurde ein Großteil der Java-API mit fundierten Kenntnissen des Java-Compilers und der JVM entwickelt, sodass Sie Leistungsüberlegungen haben, die dies möglicherweise erklären. Ich gebe zu, dass kritische Codeabschnitte, die keine Millisekunde verschwenden können, möglicherweise gegen einige dieser Regeln verstoßen müssen, aber das sollte immer als Sonderfall betrachtet werden. Zusätzliche Entwicklungszeit im Voraus zu verbringen, ist eine Anfangsinvestition, mit der zukünftige (möglicherweise lähmende) technische Schulden vermieden werden können.
Ryan Delucchi

2
Übrigens .. Ich bin der Meinung, dass die Long-Methoden-sind-schlecht-heuristisch auch für Klassen gilt. Meiner Meinung nach sind lange Klassen schlecht, weil sie dazu neigen, das Prinzip der Einzelverantwortung zu verletzen. Es würde Spaß machen, wenn Compiler Warnungen für lange Klassen und Methoden ausgeben ...
Pedro Rolo

3
@ PedroMorteRolo Da stimme ich definitiv zu. Darüber hinaus haben große Klassen wahrscheinlich einen veränderlicheren Zustand: Dies führt zu Code, der sehr schwer zu warten ist.
Ryan Delucchi

1
Beste Antwort. Ein weiterer guter Hinweis ist: Wie sehen die Kommentare im Code aus? Die Häufigkeit, mit der ich über den Code einer Person gestolpert bin, mit einer Zeile wie : // fetch Foo's credentials where Bar is "uncomplete". Das ist mit ziemlicher Sicherheit ein Funktionsname und sollte entkoppelt werden. Möchte wahrscheinlich in etwas umgestaltet werden wie: Foo.fetchCredentialWhereBarUncomplete()
Jay Edwards

28

Ich denke, das Mantra "mach nur eins" auf dieser Seite hat eine große Einschränkung. Manchmal jongliert eine Sache mit vielen Variablen. Teilen Sie eine lange Funktion nicht in eine Reihe kleinerer Funktionen auf, wenn die kleineren Funktionen lange Parameterlisten haben. Dadurch wird aus einer einzelnen Funktion eine Reihe stark gekoppelter Funktionen ohne echten individuellen Wert.


18

Eine Funktion sollte nur eines tun. Wenn Sie viele kleine Dinge in einer Funktion tun, machen Sie jedes kleine Ding zu einer Funktion und rufen Sie diese Funktionen über die lange Funktion auf.

Was Sie wirklich nicht tun möchten, ist, alle 10 Zeilen Ihrer langen Funktion zu kopieren und in kurze Funktionen einzufügen (wie in Ihrem Beispiel vorgeschlagen).


Ja, viele kleine Funktionen mit dem Copy & Paste-Muster zu

"mach eins" kann je nach Granularität richtig sein oder auch nicht. Wenn eine Funktion eine Matrix multipliziert, ist das in Ordnung. Wenn eine Funktion ein virtuelles Auto baut - das ist "eine Sache", aber es ist auch eine sehr große Sache. Es können mehrere Funktionen verwendet werden, um ein Auto Komponente für Komponente zu bauen.
void.pointer

16

Ich bin damit einverstanden, dass eine Funktion nur eines tun sollte, aber auf welcher Ebene ist das eine.

Wenn Ihre 60 Zeilen eine Sache erreichen (aus Sicht Ihres Programms) und die Teile, aus denen diese 60 Zeilen bestehen, von nichts anderem verwendet werden, sind 60 Zeilen in Ordnung.

Es hat keinen wirklichen Vorteil, es aufzubrechen, es sei denn, Sie können es in Betonstücke zerlegen, die für sich allein stehen. Die zu verwendende Metrik ist Funktionalität und keine Codezeilen.

Ich habe an vielen Programmen gearbeitet, bei denen die Autoren das Einzige auf ein extremes Niveau gebracht haben, und alles, was es letztendlich getan hat, war, es so aussehen zu lassen, als hätte jemand eine Granate zu einer Funktion / Methode genommen und sie in Dutzende nicht verbundener Teile gesprengt schwer zu folgen.

Wenn Sie Teile dieser Funktion herausziehen, müssen Sie auch berücksichtigen, ob Sie unnötigen Overhead hinzufügen und vermeiden, große Datenmengen zu übertragen.

Ich glaube, der entscheidende Punkt ist, die Wiederverwendbarkeit in dieser langen Funktion zu suchen und diese Teile herauszuziehen. Was Ihnen bleibt, ist die Funktion, ob sie 10, 20 oder 60 Zeilen lang ist.


2
+1 "Die zu verwendende Metrik ist Funktionalität und keine Codezeilen"
Cody Piersall

Eine weitere wichtige Metrik ist die Anzahl der Ebenen der Blockverschachtelung. Auf ein Minimum beschränken. Das Aufteilen einer Funktion in kleinere Teile hilft oft. Andere Dinge können ebenfalls hilfreich sein, z. B. mehrere Rückgaben.
user2367418

10

60 Zeilen sind groß, aber nicht zu lang für eine Funktion. Wenn es auf einen Bildschirm in einem Editor passt, können Sie alles auf einmal sehen. Es kommt wirklich darauf an, was die Funktionen tun.

Warum ich eine Funktion auflösen kann:

  • Es ist zu lang
  • Es macht den Code wartbarer, indem es ihn aufteilt und aussagekräftige Namen für die neue Funktion verwendet
  • Die Funktion ist nicht zusammenhängend
  • Teile der Funktion sind an sich nützlich.
  • Wenn es schwierig ist, einen aussagekräftigen Namen für die Funktion zu finden (es macht wahrscheinlich zu viel)

3
Gute Punkte, stimme ich zu, auch wenn Sie die Funktion DoThisAndThisAndAlsoThis benennen müssen, tut dies wahrscheinlich zu viel. danke :)

2
Sie sind mit diesem Kumpel einfach außer Betrieb. 60 Zeilen werden immer zu viel sein. Ich würde sagen, wenn Sie sich 10 Zeilen nähern, sind Sie wahrscheinlich nahe am Limit.
Willcodejavaforfood

Aber eine andere Funktion ruft diese Funktionen immer noch auf und ist im Wesentlichen dieselbe DoThisAndThisAndAlsoThisFunktion, aber mit viel Abstraktion, die Sie noch irgendwie benennen müssen
Timo Huovinen

6

Meine persönliche Heuristik ist, dass es zu lang ist, wenn ich das Ganze nicht sehen kann, ohne zu scrollen.


4
... während Sie die Schriftgröße auf 5 eingestellt haben?
EricSchaefer

5

Größe ca. Sie Bildschirmgröße (also holen Sie sich einen großen Pivot-Breitbildschirm und drehen Sie ihn) ... :-)

Scherz beiseite, eine logische Sache pro Funktion.

Und das Positive ist, dass Unit-Tests mit kleinen logischen Funktionen, die eine Sache erledigen, sehr viel einfacher sind. Große Funktionen, die viele Dinge tun, sind schwerer zu überprüfen!

/ Johan


Guter Punkt zum Testen der Einheit :)

5

Faustregel: Wenn eine Funktion Codeblöcke enthält, die etwas bewirken, das etwas vom Rest des Codes getrennt ist, setzen Sie sie in eine separate Funktion. Beispiel:

function build_address_list_for_zip($zip) {

    $query = "SELECT * FROM ADDRESS WHERE zip = $zip";
    $results = perform_query($query);
    $addresses = array();
    while ($address = fetch_query_result($results)) {
        $addresses[] = $address;
    }

    // now create a nice looking list of
    // addresses for the user
    return $html_content;
}

Viel schöner:

function fetch_addresses_for_zip($zip) {
    $query = "SELECT * FROM ADDRESS WHERE zip = $zip";
    $results = perform_query($query);
    $addresses = array();
    while ($address = fetch_query_result($results)) {
        $addresses[] = $address;
    }
    return $addresses;
}

function build_address_list_for_zip($zip) {

    $addresses = fetch_addresses_for_zip($zip);

    // now create a nice looking list of
    // addresses for the user
    return $html_content;
}

Dieser Ansatz hat zwei Vorteile:

  1. Wann immer Sie Adressen für eine bestimmte Postleitzahl abrufen müssen, können Sie die sofort verfügbare Funktion verwenden.

  2. Wenn Sie die Funktion jemals wieder lesen müssen, build_address_list_for_zip()wissen Sie, was der erste Codeblock tun wird (er ruft Adressen für eine bestimmte Postleitzahl ab, zumindest können Sie dies aus dem Funktionsnamen ableiten). Wenn Sie den Abfragecode inline gelassen hätten, müssten Sie zuerst diesen Code analysieren.

[Auf der anderen Seite (ich werde leugnen, dass ich Ihnen dies auch unter Folter gesagt habe): Wenn Sie viel über PHP-Optimierung lesen, könnten Sie auf die Idee kommen, die Anzahl der Funktionen so gering wie möglich zu halten, da Funktionsaufrufe sehr, sehr teuer in PHP. Das weiß ich nicht, da ich nie Benchmarks gemacht habe. In diesem Fall ist es wahrscheinlich besser, keine der Antworten auf Ihre Frage zu befolgen, wenn Ihre Anwendung sehr "leistungsempfindlich" ist ;-)]


danke schönes Beispiel :) Ich werde für Funktionsbenchmarks in PHP

5

Werfen Sie einen Blick auf McCabes Zyklomatik, in der er seinen Code in ein Diagramm aufteilt, in dem "Jeder Knoten im Diagramm einem Codeblock im Programm entspricht, in dem der Fluss sequentiell ist und die Bögen den im Programm aufgenommenen Zweigen entsprechen. ""

Stellen Sie sich nun vor, Ihr Code hat keine Funktionen / Methoden. Es ist nur eine riesige Code-Ausbreitung in Form eines Diagramms.

Sie möchten diese Ausbreitung in Methoden aufteilen. Beachten Sie, dass in jeder Methode eine bestimmte Anzahl von Blöcken vorhanden ist. Für alle anderen Methoden ist nur ein Block jeder Methode sichtbar: der erste Block (wir gehen davon aus, dass Sie nur an einem Punkt in eine Methode springen können: im ersten Block). Alle anderen Blöcke in jeder Methode sind Informationen, die in dieser Methode verborgen sind, aber jeder Block in einer Methode kann möglicherweise zu einem anderen Block in dieser Methode springen.

Um zu bestimmen, wie groß Ihre Methoden in Bezug auf die Anzahl der Blöcke pro Methode sein sollten, stellen Sie sich möglicherweise die Frage: Wie viele Methoden sollte ich haben, um die maximale potenzielle Anzahl von Abhängigkeiten (MPE) zwischen allen Blöcken zu minimieren?

Diese Antwort wird durch eine Gleichung gegeben. Wenn r die Anzahl der Methoden ist, die die MPE des Systems minimieren, und n die Anzahl der Blöcke im System ist, lautet die Gleichung: r = sqrt (n)

Und es kann gezeigt werden, dass dies die Anzahl der Blöcke pro Methode ergibt, auch sqrt (n).


4

Denken Sie daran, dass Sie am Ende nur aus Gründen des Re-Factorings ein Re-Factoring durchführen können, wodurch der Code möglicherweise unleserlicher wird als ursprünglich.

Ein ehemaliger Kollege von mir hatte eine bizarre Regel, dass eine Funktion / Methode nur 4 Codezeilen enthalten darf! Er versuchte, sich so streng daran zu halten, dass seine Methodennamen sich oft wiederholten und bedeutungslos wurden und die Aufrufe tief verschachtelt und verwirrend wurden.

Mein eigenes Mantra ist also geworden: Wenn Sie sich keinen anständigen Funktions- / Methodennamen für den Code vorstellen können, den Sie neu faktorisieren, stören Sie sich nicht.


2

Der Hauptgrund, warum ich eine Funktion normalerweise aufteile, ist entweder, dass Teile davon auch Bestandteile einer anderen Funktion in der Nähe sind, die ich schreibe, sodass die gemeinsamen Teile herausgerechnet werden. Wenn viele Felder oder Eigenschaften aus einer anderen Klasse verwendet werden, besteht eine gute Chance, dass der relevante Block im Großhandel herausgehoben und wenn möglich in die andere Klasse verschoben werden kann.

Wenn Sie einen Codeblock mit einem Kommentar oben haben, ziehen Sie in Betracht, ihn in eine Funktion zu ziehen, wobei die Funktions- und Argumentnamen den Zweck veranschaulichen, und den Kommentar für die Begründung des Codes zu reservieren.

Sind Sie sicher, dass es dort keine Teile gibt, die anderswo nützlich wären? Was ist das für eine Funktion?


Die Funktion erstellt eine Cache-Datei aus einer Vorlage, basierend auf der URL, wie post_2009_01_01.html aus der URL / post /

2

Meiner Meinung nach lautet die Antwort: Wenn es zu viele Dinge tut. Ihre Funktion sollte nur die Aktionen ausführen, die Sie vom Namen der Funktion selbst erwarten. Eine andere zu berücksichtigende Sache ist, wenn Sie einige Teile Ihrer Funktionen in anderen wiederverwenden möchten; In diesem Fall kann es nützlich sein, es zu teilen.


2

Normalerweise unterbreche ich Funktionen, indem ich Kommentare platzieren muss, die den nächsten Codeblock beschreiben. Was zuvor in den Kommentaren stand, geht jetzt in den neuen Funktionsnamen. Dies ist keine harte Regel, aber (für mich) eine nette Faustregel. Ich mag es, wenn Code für sich selbst spricht, besser als einer, der Kommentare benötigt (da ich gelernt habe, dass Kommentare normalerweise lügen)


Ich mag es, meinen Code zu kommentieren, meistens nicht für mich, sondern für andere, wodurch viele Fragen darüber beseitigt werden, wo $ variable definiert wurde, aber ich mag es auch, wenn der Code selbsterklärend ist. Lügen Kommentare?

ja, weil sie meistens nicht gepflegt werden. Zum Zeitpunkt des Schreibens sind sie möglicherweise korrekt, aber sobald ein Bugfix oder eine neue Funktion eingeführt wurde, erzwingt niemand, dass Kommentare entsprechend der neuen Situation geändert werden. Methodennamen neigen dazu, viel seltener zu lügen als Kommentare IMHO
Olaf Kock

Ich bin gerade auf diese Antwort gestoßen : stackoverflow.com/questions/406760/… mit der Aussage, dass "die meisten Kommentare im Code tatsächlich eine schädliche Form der Codeduplizierung sind". Auch - Lange Reihe von Kommentaren dort.
Olaf Kock

1

Dies ist teilweise Geschmackssache, aber wie ich dies feststelle, versuche ich, meine Funktionen ungefähr so ​​lange beizubehalten, wie sie gleichzeitig (maximal) auf meinen Bildschirm passen. Der Grund dafür ist, dass es einfacher ist zu verstehen, was passiert, wenn Sie das Ganze auf einmal sehen können.

Wenn ich codiere, ist es eine Mischung aus dem Schreiben langer Funktionen und dem Umgestalten, um Bits herauszuholen, die von anderen Funktionen wiederverwendet werden könnten, und dem Schreiben kleiner Funktionen, die diskrete Aufgaben ausführen.

Ich weiß nicht, ob es eine richtige oder falsche Antwort darauf gibt (z. B. können Sie sich auf 67 Zeilen als Ihr Maximum festlegen, aber es kann Zeiten geben, in denen es sinnvoll ist, ein paar weitere hinzuzufügen).


Nun, ich mag es auch, meine komplette Funktion auf dem Bildschirm zu sehen :) Manchmal bedeutet das eine Monospace 9-Schriftart und eine große Auflösung in einem schwarzen Hintergrund. Ich bin damit einverstanden, dass es einfacher ist, dies so zu verstehen.

1

Zu diesem Thema wurden einige gründliche Nachforschungen angestellt. Wenn Sie die wenigsten Fehler wünschen, sollte Ihr Code nicht zu lang sein. Es sollte aber auch nicht zu kurz sein.

Ich bin nicht der Meinung, dass eine Methode auf Ihre Anzeige in einer passen sollte, aber wenn Sie um mehr als eine Seite nach unten scrollen, ist die Methode zu lang.

Weitere Informationen finden Sie unter Die optimale Klassengröße für objektorientierte Software .


danke für den Link, lesen :)

1

Ich habe bereits 500 Zeilenfunktionen geschrieben, dies waren jedoch nur große switch-Anweisungen zum Dekodieren und Beantworten von Nachrichten. Als der Code für eine einzelne Nachricht komplexer wurde als ein einzelnes Wenn-Dann-Sonst, habe ich ihn extrahiert.

Obwohl die Funktion 500 Zeilen betrug, betrugen die unabhängig gepflegten Regionen im Durchschnitt 5 Zeilen.


1

Normalerweise verwende ich einen testgetriebenen Ansatz zum Schreiben von Code. Bei diesem Ansatz hängt die Funktionsgröße häufig von der Granularität Ihrer Tests ab.

Wenn Ihr Test ausreichend fokussiert ist, werden Sie aufgefordert, eine kleine fokussierte Funktion zu schreiben, um den Test zu bestehen.

Dies funktioniert auch in die andere Richtung. Funktionen müssen klein genug sein, um effektiv testen zu können. Wenn ich mit Legacy-Code arbeite, stelle ich häufig fest, dass ich größere Funktionen aufspalte, um die verschiedenen Teile davon zu testen.

Normalerweise frage ich mich, "was die Verantwortung für diese Funktion ist", und wenn ich die Verantwortung nicht in einem klaren, präzisen Satz angeben kann und dies dann in einen kleinen, fokussierten Test übersetze, frage ich mich, ob die Funktion zu groß ist.


1

Wenn es mehr als drei Verzweigungen hat, bedeutet dies im Allgemeinen, dass eine Funktion oder Methode getrennt werden sollte, um die Verzweigungslogik in verschiedene Methoden zu kapseln.

Jede for-Schleife, if-Anweisung usw. wird dann nicht als Zweig in der aufrufenden Methode angesehen.

Cobertura für Java-Code (und ich bin sicher, es gibt andere Tools für andere Sprachen) berechnet die Anzahl der if usw. in einer Funktion für jede Funktion und summiert sie für die "durchschnittliche zyklomatische Komplexität".

Wenn eine Funktion / Methode nur drei Zweige hat, erhält sie eine Drei für diese Metrik, was sehr gut ist.

Manchmal ist es schwierig, diese Richtlinie zu befolgen, und zwar zur Validierung von Benutzereingaben. Das Einfügen von Verzweigungen in verschiedene Methoden hilft jedoch nicht nur bei der Entwicklung und Wartung, sondern auch beim Testen, da die Eingaben in die Methoden, die die Verzweigung durchführen, leicht analysiert werden können, um festzustellen, welche Eingaben zu den Testfällen hinzugefügt werden müssen, um die Verzweigungen abzudecken, die wurden nicht abgedeckt.

Wenn sich alle Zweige innerhalb einer einzigen Methode befinden würden, müssten die Eingaben seit dem Start der Methode verfolgt werden, was die Testbarkeit behindert.


0

Ich vermute, Sie werden viele Antworten darauf finden.

Ich würde es wahrscheinlich basierend auf den logischen Aufgaben aufteilen, die innerhalb der Funktion ausgeführt wurden. Wenn es für Sie so aussieht, als würde Ihre Kurzgeschichte zu einem Roman, würde ich vorschlagen, bestimmte Schritte zu finden und zu extrahieren.

Wenn Sie beispielsweise eine Funktion haben, die eine Zeichenfolgeneingabe verarbeitet und ein Zeichenfolgenergebnis zurückgibt, können Sie die Funktion basierend auf der Logik zum Aufteilen Ihrer Zeichenfolge in Teile, der Logik zum Hinzufügen zusätzlicher Zeichen und der Logik zum Einfügen aufteilen alles wieder zusammen als formatiertes Ergebnis.

Kurz gesagt, was auch immer Ihren Code sauber und leicht lesbar macht (sei es, indem Sie einfach sicherstellen, dass Ihre Funktion gut kommentiert oder aufgebrochen ist), ist der beste Ansatz.


0

Unter der Annahme, dass Sie eine Sache tun, hängt die Länge ab von:

  • was machst du
  • Welche Sprache verwenden Sie?
  • Wie viele Abstraktionsebenen müssen Sie im Code behandeln?

60 Zeilen sind möglicherweise zu lang oder genau richtig. Ich vermute, dass es zu lang sein kann.


Ich mache ein

0

Eine Sache (und diese Sache sollte aus dem Funktionsnamen ersichtlich sein), aber nicht mehr als ein Bildschirm voller Code, unabhängig davon. Sie können auch Ihre Schriftgröße erhöhen. Und wenn Sie Zweifel haben, überarbeiten Sie es in zwei oder mehr Funktionen.


0

Wenn Sie vor einiger Zeit den Geist eines Tweets von Onkel Bob erweitern, wissen Sie, dass eine Funktion zu lang wird, wenn Sie das Bedürfnis haben, eine Leerzeile zwischen zwei Codezeilen zu setzen. Die Idee ist, dass, wenn Sie eine leere Zeile benötigen, um den Code zu trennen, seine Verantwortung und sein Umfang an diesem Punkt getrennt werden.


0

Meine Idee ist, dass wenn ich mich fragen muss, ob es zu lang ist, es wahrscheinlich zu lang ist. In diesem Bereich können kleinere Funktionen erstellt werden, da dies später im Lebenszyklus der Anwendung hilfreich sein kann.

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.