Ich selbst kann es kaum erwarten, eine Funktion zu schreiben, wenn ich mehr als zweimal etwas tun muss. Aber wenn es um Dinge geht, die nur zweimal auftauchen, ist es etwas kniffliger.
Für Code, der mehr als zwei Zeilen benötigt, schreibe ich eine Funktion. Aber wenn man sich Dingen wie:
print "Hi, Tom"
print "Hi, Mary"
Ich zögere zu schreiben:
def greeting(name):
print "Hi, " + name
greeting('Tom')
greeting('Mary')
Der zweite scheint zu viel, nicht wahr?
Aber was ist, wenn wir haben:
for name in vip_list:
print name
for name in guest_list:
print name
Und hier ist die Alternative:
def print_name(name_list):
for name in name_list:
print name
print_name(vip_list)
print_name(guest_list)
Die Dinge werden schwierig, nein? Es ist jetzt schwer zu entscheiden.
Was ist deine Meinung dazu?
python
coding-style
Zen
quelle
quelle
always
undnever
als rote Fahnen. Es gibt eine Sache namens "Kontext", in der diealways
undnever
-Regeln, auch wenn sie im Allgemeinen gut sind, möglicherweise nicht so angemessen sind. Hüten Sie sich vor Software-Entwicklern, die absolut handeln. ;)from itertools import chain; for name in chain(vip_list, guest_list): print(name)
.Special cases aren't special enough to break the rules. Although practicality beats purity.
Antworten:
Obwohl es ein Faktor bei der Entscheidung ist, eine Funktion abzuspalten, sollte die Häufigkeit, mit der etwas wiederholt wird, nicht der einzige Faktor sein. Oft ist es sinnvoll, eine Funktion für etwas zu erstellen, das nur einmal ausgeführt wird . Im Allgemeinen möchten Sie eine Funktion aufteilen, wenn:
Ihre Beispiele erfüllen diese Kriterien nicht. Sie wechseln von einem Einzeiler zu einem Einzeiler, und die Namen bieten Ihnen in Bezug auf Klarheit keine wirklichen Vorteile. Abgesehen davon sind solche einfachen Funktionen außerhalb von Tutorials und Schulaufgaben selten. Die meisten Programmierer neigen dazu, zu weit in die andere Richtung zu irren.
quelle
Nur wenn die Vervielfältigung beabsichtigt und nicht zufällig ist .
Oder anders ausgedrückt:
Nur wenn Sie erwarten , dass sie sich in Zukunft gemeinsam entwickeln.
Hier ist der Grund:
Manchmal zwei Teile des Codes nur passieren das gleiche worden , obwohl sie nichts miteinander zu tun haben. In diesem Fall müssen Sie sich dem Drang widersetzen, sie zu kombinieren, da diese Person beim nächsten Wartungsvorgang nicht erwartet , dass die Änderungen an einen zuvor nicht vorhandenen Aufrufer weitergegeben werden, und diese Funktion möglicherweise unterbrochen wird. Daher müssen Sie Code nur dann ausklammern, wenn es sinnvoll ist, und nicht immer dann, wenn es so aussieht, als würde es die Codegröße verringern.
Faustregel:
Wenn der Code nur neue Daten zurückgibt und keine vorhandenen Daten ändert oder andere Nebenwirkungen hat, ist es sehr wahrscheinlich, dass er als separate Funktion herausgerechnet werden kann. (Ich kann mir kein Szenario vorstellen, in dem dies zu einem Bruch führen würde, ohne die beabsichtigte Semantik der Funktion vollständig zu ändern. Zu diesem Zeitpunkt sollte sich auch der Funktionsname oder die Signatur ändern, und in diesem Fall müssten Sie trotzdem vorsichtig sein. )
quelle
Nein, es ist nicht immer eine bewährte Methode.
Alle anderen Dinge, bei denen es sich um gleichen, linearen Code handelt, sind einfacher zu lesen als Funktionsaufrufe. Ein nicht-trivialer Funktionsaufruf benötigt immer Parameter, daher müssen Sie all das sortieren und mentale kontextbezogene Sprünge von Funktionsaufruf zu Funktionsaufruf durchführen. Bevorzugen Sie immer eine bessere Code-Klarheit, es sei denn, Sie haben einen triftigen Grund für Unklarheiten (z. B. den Erhalt der erforderlichen Leistungsverbesserungen).
Warum wird Code dann in separate Methoden umgestaltet? Verbesserung der Modularität. Sammeln wichtiger Funktionen hinter einer einzelnen Methode und Vergeben eines aussagekräftigen Namens. Wenn Sie dies nicht erreichen, benötigen Sie diese separaten Methoden nicht.
quelle
Why take the performance hit of a function call when you don't get any significant benefit by doing so?
Welche Leistung hat geschlagen? Im allgemeinen Fall werden kleine Funktionen eingeblendet und der Overhead ist für große Funktionen vernachlässigbar. CPython ist wahrscheinlich nicht inline, aber niemand verwendet es für die Leistung. Ich frage auch dasline by line code...
bisschen. Es ist einfacher, wenn Sie versuchen, die Ausführung in Ihrem Gehirn zu simulieren. Aber ein Debugger wird einen besseren Job machen und zu versuchen, etwas über eine Schleife zu beweisen, indem man ihrer Ausführung folgt, ist wie zu versuchen, eine Aussage über ganze Zahlen zu beweisen, indem man sie alle durchläuft.In Ihrem speziellen Beispiel mag es übertrieben erscheinen, eine Funktion zu erstellen. stattdessen würde ich die Frage stellen: ist es möglich, dass sich dieser besondere Gruß in Zukunft ändert? Wie?
Funktionen werden nicht nur verwendet, um die Funktionalität einzuschließen und die Wiederverwendung zu vereinfachen, sondern auch, um die Änderung zu vereinfachen. Wenn sich die Anforderungen ändern, muss kopierter Code manuell gesucht und geändert werden, während der Code mit einer Funktion nur einmal geändert werden muss.
Ihr Beispiel würde davon nicht über eine Funktion profitieren - da die Logik so gut wie nicht existiert - sondern möglicherweise über eine
GREET_OPENING
Konstante. Diese Konstante könnte dann aus einer Datei geladen werden, so dass Ihr Programm beispielsweise leicht an verschiedene Sprachen angepasst werden kann. Beachten Sie, dass dies eine grobe Lösung ist. Ein komplexeres Programm würde wahrscheinlich eine verfeinerte Methode zum Nachverfolgen von i18n benötigen, dies hängt jedoch wiederum von den Anforderungen und der zu erledigenden Arbeit ab.Letztendlich geht es um mögliche Anforderungen und darum, Dinge im Voraus zu planen, um die Arbeit Ihres zukünftigen Selbst zu erleichtern.
quelle
Persönlich habe ich die Dreierregel übernommen - was ich mit einem Anruf bei YAGNI rechtfertigen werde . Wenn ich etwas tun muss, sobald ich diesen Code schreibe, kann ich es zweimal einfach kopieren / einfügen (ja, ich habe gerade zugegeben, dass ich kopiere / einfügen muss!), Weil ich es nicht noch einmal brauche, aber wenn ich dasselbe tun muss Ding wieder , dann werde ich diese Brocken in seine eigene Methode Refactoring und extrahieren, ich habe mir selbst bewiesen, dass ich werde es wieder brauchen.
Ich stimme dem zu, was Karl Bielefeldt und Robert Harvey gesagt haben, und meine Interpretation dessen, was sie sagen, ist, dass die vorrangige Regel die Lesbarkeit ist. Wenn es das Lesen meines Codes erleichtert, sollten Sie eine Funktion erstellen. Denken Sie dabei an DRY und SLAP . Wenn ich vermeiden kann, dass sich die Abstraktionsebene in meiner Funktion ändert, ist die Verwaltung in meinem Kopf einfacher. Wenn ich also nicht zwischen Funktionen wechseln kann (wenn ich nicht verstehe, was die Funktion durch einfaches Lesen ihres Namens bewirkt), bedeutet dies, dass ich weniger Schalter in meinem Kopf habe mentale Prozesse.
Ebenso muss ich den Kontext nicht zwischen Funktionen und Inline-Code wechseln, wie es
print "Hi, Tom"
für mich funktioniert. In diesem Fall könnte ich eine Funktion iff extrahierenPrintNames()
Der Rest meiner Gesamtfunktion bestand hauptsächlich aus Funktionsaufrufen.quelle
Es ist selten eindeutig, so dass Sie Optionen abwägen müssen:
In C ++ befolge ich normalerweise die Dreierregel (dh, wenn ich dasselbe zum dritten Mal benötige, baue ich es in ein ordnungsgemäß teilbares Teil um). Mit der Erfahrung ist es jedoch einfacher, diese Wahl zu treffen, da Sie mehr über den Umfang wissen. Software & Domain, mit der Sie arbeiten.
In Python ist es jedoch recht einfach, Logik wiederzuverwenden, anstatt sie zu wiederholen. Mehr als in vielen anderen Sprachen (zumindest historisch), IMO.
Überlegen Sie sich also, die Logik nur lokal wiederzuverwenden, indem Sie beispielsweise eine Liste aus lokalen Argumenten erstellen:
Sie können ein Tupel von Tupeln verwenden und es direkt in die for-Schleife aufteilen, wenn Sie mehrere Argumente benötigen:
Oder machen Sie eine lokale Funktion (vielleicht ist dies Ihr zweites Beispiel), die die Wiederverwendung der Logik explizit macht, aber auch deutlich zeigt, dass print_name () nicht außerhalb der Funktion verwendet wird:
Funktionen sind besonders dann vorzuziehen, wenn Sie die Logik in der Mitte abbrechen müssen (dh Return verwenden), da Unterbrechungen oder Ausnahmen die Dinge unnötig durcheinander bringen können.
Entweder ist es besser, dieselbe Logik, IMO, zu wiederholen, als eine globale / Klassenfunktion zu deklarieren, die nur von einem Aufrufer verwendet wird (wenn auch zweimal).
quelle
Alle Best Practices haben einen bestimmten Grund, auf den Sie sich beziehen können, um eine solche Frage zu beantworten. Sie sollten Welligkeiten immer dann vermeiden, wenn eine mögliche zukünftige Änderung auch Änderungen an anderen Komponenten impliziert.
In Ihrem Beispiel: Wenn Sie davon ausgehen, dass Sie eine Standardbegrüßung haben und sicherstellen möchten, dass sie für alle Personen gleich ist, schreiben Sie
Andernfalls müssten Sie aufpassen und die Standardbegrüßung an zwei Stellen ändern, falls sie sich ändert.
Wenn jedoch das "Hallo" zufällig dasselbe ist und das Ändern einer der Begrüßungen nicht notwendigerweise zu Änderungen für die andere führt, halten Sie sie getrennt. Bewahren Sie sie daher getrennt auf, wenn es logische Gründe für die Annahme gibt, dass die folgende Änderung wahrscheinlicher ist:
Für Ihren zweiten Teil hängt es wahrscheinlich von zwei Faktoren ab, wie viel in Funktionen "gepackt" werden soll:
Im Idealfall werden Sie denken, dass bei einer Änderung "Ich muss den größten Teil des folgenden Blocks ändern" und nicht "Ich muss den Code irgendwo in einem großen Block ändern ".
quelle
for name in "Tom", "Mary": std_greeting(name)
Der wichtigste Aspekt benannter Konstanten und Funktionen ist nicht so sehr, dass sie den Umfang der Eingabe verringern, sondern dass sie die verschiedenen Stellen "anhängen", an denen sie verwendet werden. Betrachten Sie für Ihr Beispiel vier Szenarien:
Es ist notwendig, beide Begrüßungen gleich zu ändern, [zB zu
Bonjour, Tom
undBonjour, Mary
].Es ist notwendig, eine Begrüßung zu ändern, aber die andere so zu lassen, wie sie ist [zB
Hi, Tom
undGuten Tag, Mary
].Es ist notwendig, beide Begrüßungen unterschiedlich zu ändern [zB
Hello, Tom
undHowdy, Mary
].Keine der Begrüßungen muss jemals geändert werden.
Wenn es nie notwendig ist, eine der Begrüßungen zu ändern, spielt es keine Rolle, welcher Ansatz gewählt wird. Wenn Sie eine gemeinsame Funktion verwenden, hat dies den natürlichen Effekt, dass Begrüßungen auf dieselbe Weise geändert werden. Wenn sich alle Grüße auf die gleiche Weise ändern sollten, wäre das eine gute Sache. Sollte dies jedoch nicht der Fall sein, muss die Begrüßung jeder Person separat codiert oder angegeben werden. Alle Arbeiten, die unter Verwendung einer gemeinsamen Funktion oder Spezifikation durchgeführt wurden, müssen rückgängig gemacht werden (und wären besser nicht von vornherein erledigt worden).
Es ist zwar nicht immer möglich, die Zukunft vorherzusagen, aber wenn man Grund zu der Annahme hat, dass sich beide Begrüßungen mit größerer Wahrscheinlichkeit gemeinsam ändern müssen, ist dies ein Faktor für die Verwendung von gemeinsamem Code (oder einer benannten Konstante). ; Wenn man Grund zu der Annahme hat, dass es wahrscheinlicher ist, dass sich einer oder beide ändern müssen, damit sie sich unterscheiden, ist dies ein Faktor, der gegen die Verwendung von gemeinsamem Code spricht.
quelle
Ich denke, Sie sollten einen Grund haben, ein Verfahren zu erstellen. Es gibt eine Reihe von Gründen, eine Prozedur zu erstellen. Die, die ich für am wichtigsten halte, sind:
Abstraktion
Eine Prozedur kann verwendet werden, um einen allgemeinen Algorithmus von den Details bestimmter Schritte im Algorithmus zu abstrahieren. Wenn ich eine passend zusammenhängende Abstraktion finde, hilft mir dies, die Art und Weise zu strukturieren, in der ich über die Funktionsweise des Algorithmus nachdenke. Zum Beispiel kann ich einen Algorithmus entwerfen, der mit Listen arbeitet, ohne unbedingt die Listendarstellung berücksichtigen zu müssen.
Modularität
Prozeduren können verwendet werden, um Code in Modulen zu organisieren. Die Module können oft separat behandelt werden. Zum Beispiel separat gebaut und getestet.
Ein gut gestaltetes Modul erfasst normalerweise eine zusammenhängende sinnvolle Funktionseinheit. Daher können sie häufig verschiedenen Teams gehören, vollständig durch eine Alternative ersetzt oder in einem anderen Kontext wiederverwendet werden.
Code-Navigation
In großen Systemen kann es schwierig sein, den mit einem bestimmten Systemverhalten verknüpften Code zu finden. Die hierarchische Organisation des Codes in Bibliotheken, Modulen und Prozeduren kann bei dieser Herausforderung hilfreich sein. Insbesondere, wenn Sie versuchen, a) Funktionen unter aussagekräftigen und vorhersehbaren Namen zu organisieren, b) die Prozeduren in Bezug auf ähnliche Funktionen nebeneinander zu platzieren.
Aktualisieren Sie die Konsistenz
In großen Systemen kann es schwierig sein, den gesamten Code zu finden, der geändert werden muss, um eine bestimmte Verhaltensänderung zu erzielen. Die Verwendung von Prozeduren zum Organisieren der Funktionalität des Programms kann dies erleichtern. Insbesondere, wenn jede Funktion Ihres Programms nur einmal und in einer zusammenhängenden Gruppe von Prozeduren vorkommt, ist es (meiner Erfahrung nach) weniger wahrscheinlich, dass Sie irgendwo fehlen, wo Sie eine Aktualisierung hätten vornehmen oder eine inkonsistente Aktualisierung vornehmen müssen.
Beachten Sie, dass Sie Prozeduren basierend auf der Funktionalität und den Abstraktionen im Programm organisieren sollten. Nicht basierend darauf, ob zwei Codebits momentan gleich sind.
Rekursion
Für die Verwendung der Rekursion müssen Sie Prozeduren erstellen
Testen
In der Regel können Sie Abläufe unabhängig voneinander testen. Das unabhängige Testen verschiedener Teile des Hauptteils einer Prozedur ist schwieriger, da Sie normalerweise den ersten Teil der Prozedur vor dem zweiten Teil ausführen müssen. Diese Beobachtung trifft häufig auch auf andere Ansätze zur Spezifizierung / Überprüfung des Verhaltens von Programmen zu.
Fazit
Viele dieser Punkte beziehen sich auf die Verständlichkeit des Programms. Sie können sagen, dass Verfahren eine Möglichkeit sind, eine neue Sprache für Ihre Domäne zu erstellen, mit der Sie Probleme und Prozesse in Ihrer Domäne organisieren, schreiben und lesen können.
quelle
Keiner der von Ihnen angegebenen Fälle scheint eine Umgestaltung wert zu sein.
In beiden Fällen führen Sie eine Operation aus, die klar und prägnant ausgedrückt wird, und es besteht keine Gefahr, dass eine inkonsistente Änderung vorgenommen wird.
Ich empfehle, dass Sie immer nach Möglichkeiten suchen, Code zu isolieren, wenn:
Es ist eine identifizierbare, sinnvolle Aufgabe , die Sie trennen könnten, und
Entweder
ein. die Aufgabe ist komplex auszudrücken (unter Berücksichtigung der Ihnen zur Verfügung stehenden Funktionen) oder
b. Die Aufgabe wird mehrmals ausgeführt, und Sie müssen sicherstellen, dass sie an beiden Stellen auf dieselbe Weise geändert wird.
Wenn die Bedingung 1 nicht erfüllt ist, werden Sie nicht die richtige Schnittstelle für den Code finden. Wenn Sie versuchen, sie zu erzwingen, werden Sie am Ende eine Menge Parameter, mehrere Dinge, die Sie zurückgeben möchten, eine Menge kontextbezogener Logik und möglicherweise eine Menge davon haben keinen guten Namen finden. Versuchen Sie zunächst, die Schnittstelle zu dokumentieren, an die Sie denken. Auf diese Weise können Sie die Hypothese testen, dass es sich um die richtige Bündelung von Funktionen handelt, und mit dem zusätzlichen Vorteil, dass der Code beim Schreiben bereits definiert und dokumentiert ist!
2a ist ohne 2b möglich: Manchmal habe ich Code aus dem Flow entfernt, auch wenn ich weiß, dass er nur einmal verwendet wird, einfach weil das Verschieben und Ersetzen durch eine einzelne Zeile dazu führt, dass der Kontext, in dem er aufgerufen wird, plötzlich viel besser lesbar ist (insbesondere, wenn es sich um ein einfaches Konzept handelt, dessen Implementierung die Sprache schwierig macht). Beim Lesen der extrahierten Funktion wird auch deutlich, wo die Logik beginnt und endet und was sie tut.
2b ist ohne 2a möglich: Der Trick ist, ein Gefühl dafür zu haben, welche Art von Änderungen wahrscheinlicher sind. Ist es wahrscheinlicher, dass sich Ihre Unternehmensrichtlinie von "Hallo" überall zu "Hallo" ändert, oder dass sich Ihre Begrüßung zu einem formaleren Ton ändert, wenn Sie eine Zahlungsaufforderung oder eine Entschuldigung für einen Serviceausfall senden? Manchmal liegt es vielleicht daran, dass Sie eine externe Bibliothek verwenden, bei der Sie sich nicht sicher sind und die Sie schnell gegen eine andere austauschen möchten: Die Implementierung kann sich ändern, auch wenn die Funktionalität dies nicht tut.
Meistens haben Sie jedoch eine Mischung aus 2a und 2b. Und Sie müssen Ihr Urteilsvermögen einsetzen und dabei den geschäftlichen Wert des Codes, die Häufigkeit seiner Verwendung, den Zustand Ihrer Testsuite usw. berücksichtigen.
Wenn Sie die gleiche Logik bemerken, die mehr als einmal verwendet wurde, sollten Sie auf jeden Fall die Gelegenheit nutzen, über ein Refactoring nachzudenken. Wenn Sie
n
in den meisten Sprachen mit neuen Anweisungen beginnen, die mehr als die Einrückungsstufen überschreiten, ist dies ein weiterer, geringfügig weniger wichtiger Auslöser (wählen Sie einen Wert, mit demn
Sie für die jeweilige Sprache vertraut sind: Python könnte beispielsweise 6 sein).Solange Sie über diese Dinge nachdenken und die großen Spaghetti-Code-Monster niederschlagen, sollte es Ihnen gut gehen - machen Sie sich keine Gedanken darüber, wie feinkörnig Ihr Refactoring sein muss, dass Sie keine Zeit haben für Dinge wie Tests oder Dokumentation aufgearbeitet. Wenn es getan werden muss, wird die Zeit zeigen.
quelle
Im Allgemeinen stimme ich Robert Harvey zu, wollte aber einen Fall hinzufügen, um eine Funktionalität in Funktionen aufzuteilen. Zur Verbesserung der Lesbarkeit. Betrachten Sie einen Fall:
Obwohl diese Funktionsaufrufe nirgendwo anders verwendet werden, wird die Lesbarkeit erheblich verbessert, wenn alle drei Funktionen sehr lang sind und verschachtelte Schleifen usw. aufweisen.
quelle
Es gibt keine feste Regel, die angewendet werden muss. Sie hängt von der tatsächlich verwendeten Funktion ab. Für den einfachen Namensdruck würde ich keine Funktion verwenden, aber wenn es eine mathematische Summe ist, wäre das eine andere Geschichte. Sie würden dann eine Funktion erstellen, auch wenn sie nur zweimal aufgerufen wird. Dies soll sicherstellen, dass die mathematische Summe immer dieselbe ist, wenn sie jemals geändert wird. In einem anderen Beispiel, wenn Sie irgendeine Form der Validierung durchführen, würden Sie eine Funktion verwenden. Wenn Sie also in Ihrem Beispiel überprüfen müssen, ob der Name länger als 5 Zeichen ist, würden Sie eine Funktion verwenden, um sicherzustellen, dass immer die gleichen Validierungen durchgeführt werden.
Ich denke, Sie haben Ihre eigene Frage beantwortet, als Sie sagten: "Für Codes, die mehr als zwei Zeilen benötigen, muss ich eine Funk schreiben". Im Allgemeinen würden Sie eine Funktion verwenden, aber Sie müssen auch Ihre eigene Logik verwenden, um festzustellen, ob die Verwendung einer Funktion einen Mehrwert bietet.
quelle
Ich bin zu der Überzeugung gelangt, dass etwas über das Refactoring hier nicht erwähnt wurde. Ich weiß, dass es hier bereits viele Antworten gibt, aber ich denke, das ist neu.
Ich bin seit jeher ein skrupelloser Umgestalter und ein starker Anhänger von DRY. Meistens liegt es daran, dass ich Probleme habe, eine große Codebasis in meinem Kopf zu behalten, und teilweise daran, dass mir DRY-Codierung und C & P-Codierung nichts Spaß machen. Tatsächlich ist es für mich schmerzhaft und furchtbar langsam.
Die Sache ist, auf DRY zu bestehen, hat mir viel Übung in einigen Techniken gegeben, die ich selten bei anderen sehe. Viele Leute bestehen darauf, dass es schwierig oder unmöglich ist, Java zu DRY zu machen, aber sie versuchen es einfach nicht.
Ein Beispiel von vor langer Zeit, das Ihrem Beispiel etwas ähnlich ist. Die Leute neigen dazu zu denken, dass die Erstellung einer Java-GUI schwierig ist. Natürlich ist es so, wenn Sie wie folgt codieren:
Jeder, der das für verrückt hält, hat absolut Recht, aber es ist nicht Javas Schuld - Code sollte niemals so geschrieben werden. Diese Methodenaufrufe sind Funktionen, die in andere Systeme eingebunden werden sollen. Wenn Sie ein solches System nicht finden können, bauen Sie es!
Offensichtlich können Sie so keinen Code erstellen, also müssen Sie einen Schritt zurücktreten und sich das Problem ansehen. Was macht dieser wiederholte Code tatsächlich? Es spezifiziert einige Zeichenketten und ihre Beziehung (einen Baum) und verbindet die Blätter dieses Baums zu Aktionen. Also, was Sie wirklich wollen, ist zu sagen:
Sobald Sie Ihre Beziehung auf eine Art und Weise definiert haben, die prägnant und beschreibend ist, schreiben Sie eine Methode, um damit umzugehen. In diesem Fall durchlaufen Sie die Methoden der übergebenen Klasse und erstellen einen Baum. Verwenden Sie dann diese Methode, um Ihre Menüs zu erstellen und Aktionen sowie (offensichtlich) ein Menü anzeigen. Sie werden keine Duplikate haben und Ihre Methode ist wiederverwendbar ... und wahrscheinlich einfacher zu schreiben, als es eine große Anzahl von Menüs gewesen wäre, und wenn Sie tatsächlich Spaß am Programmieren haben, hatten Sie viel mehr Spaß. Das ist nicht schwer - die Methode, die Sie schreiben müssen, besteht wahrscheinlich aus weniger Zeilen als das Erstellen Ihres Menüs von Hand!
Um dies gut zu machen, muss man viel üben. Sie müssen genau analysieren können, welche eindeutigen Informationen in den wiederholten Abschnitten enthalten sind, diese Informationen extrahieren und herausfinden, wie Sie sie gut ausdrücken können. Das Erlernen der Verwendung von Tools wie Zeichenfolgenanalyse und Anmerkungen ist sehr hilfreich. Es ist auch sehr wichtig, zu lernen, wie man Fehlerberichte und -dokumentationen wirklich klar macht.
Sie erhalten "freies" Üben, indem Sie einfach gut codieren - wenn Sie erst einmal gut darin sind, werden Sie feststellen, dass das Codieren von DRY (einschließlich des Schreibens eines wiederverwendbaren Tools) schneller ist als das Kopieren und Einfügen und alle Fehler, duplizierten Fehler und schwierige Änderungen, die diese Art der Codierung verursacht.
Ich glaube nicht, dass ich meine Arbeit genießen könnte, wenn ich nicht so viel DRY-Techniken und Werkzeuge üben würde, wie ich könnte. Wenn ich eine Lohnkürzung vornehmen müsste, um keine Programme kopieren und einfügen zu müssen, würde ich das übernehmen.
Also meine Punkte sind:
quelle
Im Allgemeinen ist es eine gute Idee, etwas in eine Funktion zu unterteilen, die die Lesbarkeit Ihres Codes verbessert, oder wenn der Teil, der oft wiederholt wird, ein Kern des Systems ist. Wenn Sie im obigen Beispiel die Benutzer je nach Gebietsschema begrüßen müssen, ist eine separate Begrüßungsfunktion sinnvoll.
quelle
Als Folge des Kommentars von @ DocBrown an @RobertHarvey zur Verwendung von Funktionen zur Erstellung von Abstraktionen: Wenn Sie keinen ausreichend informativen Funktionsnamen finden können, der nicht wesentlich prägnanter oder klarer als der dahinter stehende Code ist, abstrahieren Sie nicht viel . Fehlt ein anderer wichtiger Grund, um eine Funktion zu erstellen, ist dies nicht erforderlich.
Außerdem erfasst ein Funktionsname selten seine vollständige Semantik, sodass Sie möglicherweise seine Definition überprüfen müssen, wenn er nicht häufig genug verwendet wird, um vertraut zu sein. Insbesondere in einer anderen Sprache als einer funktionalen Sprache müssen Sie möglicherweise wissen, ob sie Nebenwirkungen hat, welche Fehler auftreten können und wie auf diese reagiert wird, wie komplex sie ist, ob sie Ressourcen zuweist und / oder freigibt und ob es sich um eine Thread-Sprache handelt. sicher.
Natürlich betrachten wir hier per definitionem nur einfache Funktionen, aber das geht in beide Richtungen - In solchen Fällen ist es unwahrscheinlich, dass Inlining die Komplexität erhöht. Darüber hinaus wird der Leser wahrscheinlich nicht erkennen, dass es sich um eine einfache Funktion handelt, bis er nachschaut. Selbst mit einer IDE, die Sie mit der Definition verknüpft, ist das visuelle Herumspringen ein Hindernis für das Verständnis.
Im Allgemeinen führt die rekursive Zerlegung von Code in mehrere kleinere Funktionen zu einem Punkt, an dem die Funktionen keine eigenständige Bedeutung mehr haben, da die Codefragmente, aus denen sie bestehen, durch den erstellten Kontext eine größere Bedeutung erhalten nach dem umgebenden Code. Stellen Sie es sich als Analogie wie ein Bild vor: Wenn Sie zu stark zoomen, können Sie nicht erkennen, was Sie sehen.
quelle
isWeekend
wird ein Kinderspiel.