Ich stoße häufig auf dieses Problem. Zum Beispiel schreibe ich derzeit eine Lesefunktion und eine Schreibfunktion, und beide prüfen, ob buf
es sich um einen NULL-Zeiger handelt und ob sich die mode
Variable innerhalb bestimmter Grenzen befindet.
Dies ist Code-Duplikation. Dies kann gelöst werden, indem es in seine eigene Funktion versetzt wird. Aber soll ich? Dies wird eine ziemlich anämische Funktion sein (macht nicht viel), eher lokalisiert (also nicht für allgemeine Zwecke) und steht nicht gut für sich allein (kann nicht herausfinden, wofür Sie es brauchen, es sei denn, Sie sehen, wo es ist gebraucht). Eine andere Möglichkeit ist die Verwendung eines Makros, aber ich möchte in diesem Beitrag auf Funktionen eingehen.
Sollten Sie für so etwas eine Funktion verwenden? Was sind die Vor- und Nachteile?
quelle
Antworten:
Dies ist eine großartige Nutzung von Funktionen.
Das ist gut. Funktionen sollten nur eines tun.
Machen Sie es in einer OO-Sprache privat.
Wenn es mehr als einen Fall behandelt, ist es ein allgemeiner Zweck. Darüber hinaus ist die Verallgemeinerung nicht die einzige Verwendung von Funktionen. Sie dienen in der Tat dazu, (1) dass Sie denselben Code mehr als einmal schreiben müssen, und (2) den Code in kleinere Teile aufzuteilen, um ihn besser lesbar zu machen. In diesem Fall werden sowohl (1) als auch (2) erreicht. Selbst wenn Ihre Funktion von nur einer Stelle aus aufgerufen wurde, kann sie dennoch bei (2) helfen.
Überlegen Sie sich einen guten Namen, und er steht für sich allein. "ValidateFileParameters" oder so. Jetzt steht gut für sich.
quelle
Es sollte also total eine Funktion sein.
Deutlich lesbarer und wartbarer (wenn sich die Prüflogik jemals ändert, ändern Sie sie nur an einer Stelle).
Außerdem werden solche Dinge leicht eingebunden, so dass Sie sich nicht einmal Gedanken über Funktionsaufruf-Overheads machen müssen.
Lass mich dir eine bessere Frage stellen. Wie ist das nicht eine gute Übung?
Tue das Richtige. :)
quelle
return buffer != null;
ist, verletzen Sie dort die Lesbarkeit.isBufferValid
ist definitiv lesbarer (in meinem Buch) alsbuffer != null
, weil es den Zweck klarer kommuniziert. Ganz zu schweigen davon, dass Sie auch hier vor Duplikaten geschützt sind. Was brauchst du noch?IMO, Codeausschnitte sind es wert, in ihre eigenen Funktionen verschoben zu werden, wenn dies die Lesbarkeit des Codes verbessert , unabhängig davon, ob die Funktion sehr kurz ist oder nur einmal verwendet wird.
Natürlich gibt es Grenzen, die vom gesunden Menschenverstand vorgegeben werden. Sie möchten die
WriteToConsole(text)
Methode nicht haben, wenn der KörperConsole.WriteLine(text)
zum Beispiel einfach ist. Es ist jedoch eine gute Praxis, sich in der Lesbarkeit zu irren.quelle
Im Allgemeinen ist es eine gute Idee, Funktionen zu verwenden, um Doppelungen im Code zu entfernen.
Allerdings kann es zu weit treiben . Dies ist ein Urteilsspruch.
Am Beispiel Ihrer Nullpufferprüfung würde ich wahrscheinlich sagen, dass der folgende Code klar genug ist und nicht in eine separate Funktion extrahiert werden sollte, selbst wenn an einigen Stellen dasselbe Muster verwendet wird.
Wenn Sie die Fehlermeldung als Parameter für eine generische Nullprüffunktion angeben und den Code berücksichtigen, der zum Definieren der Funktion erforderlich ist, ist dies keine Netto-LOC-Einsparung. Ersetzen Sie dies durch:
Darüber hinaus bedeutet das Eintauchen in die Funktion, um zu sehen, was sie beim Debuggen tut, dass der Funktionsaufruf für den Benutzer weniger "transparent" ist und daher als weniger lesbar / wartbar angesehen werden kann.
quelle
Das Zentralisieren des Codes ist normalerweise immer eine gute Idee. Wir müssen den Code so oft wie möglich wiederverwenden.
Es ist jedoch wichtig zu wissen, wie das geht. Wenn Sie zum Beispiel einen Code haben, der compute_prime_number () oder check_if_packet_is_bad () ausführt, ist er gut. Es besteht die Möglichkeit, dass sich der Algorithmus der Funktionalität selbst weiterentwickelt und davon profitiert.
Jeder Code, der sich als Prosa wiederholt, kann jedoch nicht sofort zentralisiert werden. Das ist schlecht. Sie können beliebige Codezeilen in einer Funktion ausblenden, um einen Code im Laufe der Zeit auszublenden. Wenn mehrere Teile der Anwendung verwendet werden, müssen sie alle mit den Anforderungen aller Angerufenen der Funktion kompatibel bleiben.
Hier sind einige Fragen, die Sie stellen sollten, bevor Sie sie stellen
Hat die Funktion, die Sie erstellen, eine eigene inhärente Bedeutung, oder handelt es sich nur um ein Bündel von Zeilen?
In welchem anderen Kontext müssen dieselben Funktionen verwendet werden? Ist es wahrscheinlich, dass Sie die API etwas verallgemeinern müssen, bevor Sie diese verwenden?
Welche Erwartungen haben (verschiedene Teile der) Anwendungen, wenn Sie Ausnahmen auslösen?
In welchen Szenarien werden sich die Funktionen weiterentwickeln?
Sie sollten auch prüfen, ob solche Sachen bereits existieren. Ich habe so viele Leute gesehen, die immer dazu neigten, ihre Makros MIN, MAX neu zu definieren, anstatt nach dem zu suchen, was bereits existiert.
Im Wesentlichen stellt sich die Frage: "Ist diese neue Funktion wirklich wiederverwendbar, oder handelt es sich nur um Kopieren und Einfügen ?" Wenn es das erste ist, ist es gut zu gehen.
quelle
Codeduplizierung sollte vermieden werden. Jedes Mal, wenn Sie damit rechnen, sollten Sie eine Codeduplizierung vermeiden. Wenn Sie nicht damit gerechnet haben, wenden Sie die Regel 3: refactor an, bevor derselbe Code dreimal dupliziert wird.
Was ist eine Codeduplizierung?
Betrachten Sie das folgende Beispiel:
wird
Sie haben die Kapselung (jetzt können Sie die Bedingungen für den Status eines Administrators transparent ändern) und die Semantik des Codes verbessert. Wenn ein Fehler entdeckt wird, der darin besteht, dass Sie überprüfen, ob der Benutzer ein Administrator ist, müssen Sie nicht Ihre gesamte Codebasis ausgeben und überall eine Korrektur vornehmen (wodurch das Risiko besteht, einen zu vergessen und eine Sicherheitslücke in Ihrer Anwendung zu bekommen).
quelle
Bei DRY geht es darum, die Code-Manipulation zu vereinfachen. Sie haben gerade einen feinen Punkt über dieses Prinzip angesprochen: Es geht nicht darum, die Anzahl der Token in Ihrem Code zu minimieren, sondern vielmehr darum, einzelne Änderungspunkte für semantisch äquivalenten Code zu erstellen . Es hört sich so an, als ob Ihre Prüfungen immer dieselbe Semantik haben. Sie sollten daher in eine Funktion eingefügt werden, falls Sie sie ändern müssen.
quelle
Wenn Sie es doppelt sehen, sollten Sie einen Weg finden, es zu zentralisieren.
Funktionen sind ein guter Weg (vielleicht nicht der beste, aber das hängt von der Sprache ab). Auch wenn die Funktion anämisch ist, heißt das nicht, dass dies auch so bleibt.
Was ist, wenn Sie auch nach etwas anderem suchen müssen?
Werden Sie alle Stellen finden, an denen Sie den zusätzlichen Check hinzufügen oder einfach eine Funktion ändern müssen?
quelle
Es ist fast immer gut, wenn folgende Bedingungen erfüllt sind:
In größerem Umfang müssen Sie die Duplizierung sorgfältig gegen die Abhängigkeitsabwägungen abwägen. Beispiele für Techniken zur Einschränkung des Gültigkeitsbereichs: Verstecken in privaten Bereichen oder Modulen, ohne diese öffentlich zugänglich zu machen.
quelle