Stellen Sie sich eine parameterlose ( edit: not required) Funktion vor, die eine einzelne Codezeile ausführt und nur einmal im Programm aufgerufen wird (obwohl es nicht ausgeschlossen ist, dass sie in Zukunft erneut benötigt wird).
Es könnte eine Abfrage durchführen, einige Werte überprüfen, etwas mit Regex tun ... irgendetwas Obskures oder "Hackiges".
Das Grundprinzip dahinter wäre, schwer lesbare Auswertungen zu vermeiden:
if (getCondition()) {
// do stuff
}
wo getCondition()
ist die einzeilige Funktion.
Meine Frage ist einfach: Ist das eine gute Praxis? Es scheint mir in Ordnung zu sein, aber ich weiß nicht über die langfristige ...
getCondition
? Wenn es so klein ist und nur selten verwendet wird, wie Sie sagen, bringt es nichts, wenn Sie ihm einen Namen geben.Antworten:
Kommt auf die eine Zeile an. Wenn die Zeile für sich selbst lesbar und übersichtlich ist, wird die Funktion möglicherweise nicht benötigt. Einfaches Beispiel:
OTOH, wenn die Funktion einer Codezeile, die z. B. einen komplexen, schwer lesbaren Ausdruck enthält, einen guten Namen gibt, ist dies (für mich) vollkommen gerechtfertigt. Erfundenes Beispiel (hier zur besseren Lesbarkeit in mehrere Zeilen unterteilt):
quelle
taxPayer
in diesem Szenario global ist. Vielleicht istTaxReturn
undtaxPayer
ist diese Klasse ein Attribut.Ja, dies kann verwendet werden, um Best Practices zu erfüllen. Zum Beispiel ist es besser, eine klar benannte Funktion eine Arbeit machen zu lassen, auch wenn sie nur eine Zeile lang ist, als diese Codezeile in einer größeren Funktion zu haben und einen einzeiligen Kommentar zu benötigen, der erklärt, was sie tut. Außerdem sollten benachbarte Codezeilen Aufgaben auf derselben Abstraktionsebene ausführen. Ein Gegenbeispiel wäre so etwas wie
In diesem Fall ist es definitiv besser, die Mittellinie in eine sinnvoll benannte Funktion zu verschieben.
quelle
petrolFlag |= 0x006A;
ohne irgendeine Art von Entscheidungsfindung sagen, ist es besser, einfachpetrolFlag |= A_B_C;
ohne eine zusätzliche Funktion zu sagen . VermutlichengageChoke()
sollte nur aufgerufen werden, wennpetrolFlag
ein bestimmtes Kriterium erfüllt ist und das klar sagen sollte: "Ich brauche hier eine Funktion." Nur eine Kleinigkeit, diese Antwort ist im Grunde genau richtig :)mixLeadedGasoline()
, müssten Sie nicht!Ich denke, dass eine solche Funktion in vielen Fällen einen guten Stil hat, aber Sie können eine lokale boolesche Variable als Alternative in Betracht ziehen, wenn Sie diese Bedingung nicht an einer anderen Stelle verwenden müssen, z.
Dies gibt dem Codeleser einen Hinweis und erspart die Einführung einer neuen Funktion.
quelle
IsEngineReadyUnlessItIsOffOrBusyOrOutOfService
. B. ).Zusätzlich zu Peters Antwort , wenn diese Bedingung zu einem späteren Zeitpunkt möglicherweise aktualisiert werden muss, können Sie festlegen, dass nur ein einziger Bearbeitungspunkt vorhanden sein soll.
Nach Peters Vorbild, wenn das so ist
wird dies
Sie nehmen eine einzelne Bearbeitung vor und sie wird allgemein aktualisiert. In Bezug auf die Wartbarkeit ist dies ein Plus.
In Bezug auf die Leistung werden die meisten optimierenden Compiler den Funktionsaufruf entfernen und den kleinen Codeblock trotzdem einbinden. Wenn Sie so etwas optimieren, kann die Blockgröße tatsächlich verringert werden (indem Sie die für den Funktionsaufruf, die Rückgabe usw. erforderlichen Anweisungen löschen), sodass dies normalerweise auch unter Bedingungen möglich ist, die sonst ein Inlining verhindern könnten.
quelle
seemsGreen
Lightweight-Objekte unzuverlässig sind, ist irrelevant, wenn sich Code nie darum kümmert, ob Lightweight-Objekte grün sind. Wenn sich die Definition von "Lightweight" jedoch ändert, sodass einige nicht-grüne Objekte, für die true zurückgegebenseemsGreen
wird, nicht als "Lightweight" gemeldet werden, kann eine solche Änderung der Definition von "Lightweight" den Code zum Testen von Objekten beschädigen Grün sein". In einigen Fällen wird die Beziehung zwischen den Tests klarer, wenn im Code auf Grün und Gewicht geprüft wird, als wenn es sich um separate Methoden handelt.Zusätzlich zur Lesbarkeit (oder in Ergänzung dazu) können Funktionen auf der richtigen Abstraktionsebene geschrieben werden.
quelle
Es hängt davon ab, ob. Manchmal ist es besser, einen Ausdruck in eine Funktion / Methode zu kapseln, auch wenn es sich nur um eine Zeile handelt. Wenn das Lesen kompliziert ist oder Sie es an mehreren Stellen benötigen, halte ich es für eine gute Übung. Auf lange Sicht ist es einfacher zu warten, da Sie einen einzigen Änderungspunkt und eine bessere Lesbarkeit eingeführt haben .
Manchmal ist es jedoch nur etwas, was Sie nicht brauchen. Wenn der Ausdruck ohnehin leicht zu lesen ist und / oder nur an einer Stelle erscheint, dann wickeln Sie ihn nicht um.
quelle
Ich denke, wenn Sie nur ein paar davon haben, ist es in Ordnung, aber das Problem tritt auf, wenn viele davon in Ihrem Code enthalten sind. Und wenn der Compiler ausgeführt wird oder der Interpitor (abhängig von der verwendeten Sprache), wird diese Funktion im Speicher abgelegt. Nehmen wir also an, Sie haben 3 davon. Ich glaube nicht, dass der Computer dies bemerkt. Wenn Sie jedoch anfangen, 100 dieser kleinen Dinge zu haben, muss das System Funktionen im Speicher registrieren, die nur einmal aufgerufen und dann nicht zerstört werden.
quelle
Genau das habe ich kürzlich in einer Anwendung getan, die ich überarbeitet habe, um die tatsächliche Bedeutung des Codes ohne Kommentare zu verdeutlichen:
quelle
if
Kurzform zu halten ? Dieser lokale Ansatz (Lambda) erschwert dasPaymentButton_Click
Lesen der Funktion (insgesamt). DaslblCreditCardError
in Ihrem Beispiel scheint ein Mitglied zu sein, alsoHaveError
ist es auch ein (privates) Prädikat, das für das Objekt gültig ist. Ich würde dies eher ablehnen, aber ich bin kein C # -Programmierer, also widersetze ich mich.CheckInputs()
???Wenn Sie diese eine Zeile in eine gut benannte Methode verschieben, wird der Code leichter lesbar. Viele andere haben dies bereits erwähnt ("selbstdokumentierender Code"). Der andere Vorteil beim Übertragen in eine Methode besteht darin, dass es einfacher ist, einen Komponententest durchzuführen. Wenn es in einer eigenen Methode isoliert und in einer Einheit getestet ist, können Sie sicher sein, dass ein gefundener Fehler nicht in dieser Methode enthalten ist.
quelle
Es gibt bereits viele gute Antworten, aber es gibt einen erwähnenswerten Sonderfall .
Wenn Ihre einzeilige Anweisung einen Kommentar benötigt und Sie in der Lage sind, den Zweck klar zu identifizieren (was bedeutet: Name), sollten Sie eine Funktion extrahieren und den Kommentar in das API-Dokument einbinden. Auf diese Weise machen Sie den Funktionsaufruf einfacher, schneller und verständlicher.
Interessanterweise kann das Gleiche getan werden, wenn derzeit nichts zu tun ist, sondern ein Kommentar, der an notwendige Erweiterungen erinnert (in naher Zukunft 1) .
könnte ebenso gut geändert werden
1) Sie sollten sich wirklich sicher sein (siehe YAGNI- Prinzip)
quelle
Wenn die Sprache dies unterstützt, verwende ich normalerweise gekennzeichnete anonyme Funktionen, um dies zu erreichen.
IMHO ist dies ein guter Kompromiss, da Sie den Vorteil der Lesbarkeit haben, dass der komplizierte Ausdruck die
if
Bedingung nicht überfrachtet , während der globale Namespace / Package-Namespace nicht mit kleinen Wegwerfetiketten überfrachtet wird. Es hat den zusätzlichen Vorteil, dass die Funktion "Definition" genau dort eingesetzt wird, wo sie verwendet wird, wodurch es einfach ist, die Definition zu ändern und zu lesen.Es müssen nicht nur Prädikatfunktionen sein. Ich mag es auch, wiederholte Boiler-Platten in kleine Funktionen wie diese einzuschließen. Das folgende Beispiel ist zu stark vereinfacht, wenn Sie mit PIL in Python arbeiten
quelle
[] == False
oder etwas anderes nicht wissen Eine ähnliche pythonische Äquivalenz, die nicht immer intuitiv ist. Dies ist im Grunde eine Möglichkeit, zu kennzeichnen, dass someCondition tatsächlich ein Prädikat ist.[] != False
sondern[]
ist False als wenn sie an einen Bool werfenlen([complicated expression producing a list]) == 0
Verwendung, beiTrue if [blah] else False
der der Leser weiterhin wissen muss, dass [] Falsch ergibt.