Angenommen, ich habe eine lange Methode wie diese:
public void SomeLongMethod()
{
// Some task #1
...
// Some task #2
...
}
Diese Methode enthält keine sich wiederholenden Teile, die in eine separate Methode oder lokale Funktion verschoben werden sollten.
Es gibt viele Leute (einschließlich mir), die denken, dass lange Methoden Code-Gerüche sind. Ich mag auch keine Idee, hier #region
(s) zu verwenden, und es gibt eine sehr beliebte Antwort, die erklärt, warum dies schlecht ist .
Aber wenn ich diesen Code in Methoden aufteile
public void SomeLongMethod()
{
Task1();
Task2();
}
private void Task1()
{
// Some task #1
...
}
private void Task2()
{
// Some task #1
...
}
Ich sehe die folgenden Probleme:
Verschmutzenden Klassendefinition Umfang mit Definitionen , die intern von einem einzigen Verfahren verwendet werden und was bedeuten soll ich irgendwo dokumentieren , dass
Task1
undTask2
sind nur für den Interna von gedachtSomeLongMethod
(oder jede Person , die mein Code liest muss diese Idee ableiten).Verschmutzende IDE-Autovervollständigung (z. B. Intellisense) von Methoden, die innerhalb der einzelnen
SomeLongMethod
Methode nur einmal verwendet werden.
Wenn ich diesen Methodencode in lokale Funktionen aufteile
public void SomeLongMethod()
{
Task1();
Task2();
void Task1()
{
// Some task #1
...
}
void Task2()
{
// Some task #1
...
}
}
dann hat dies nicht die Nachteile separater Methoden, aber dies sieht (zumindest für mich) nicht besser aus als die ursprüngliche Methode.
Welche Version von SomeLongMethod
ist für Sie wartbarer und lesbarer und warum?
quelle
Antworten:
In sich geschlossene Aufgaben sollten in eigenständige Methoden verschoben werden. Es gibt keinen Nachteil, der groß genug ist, um dieses Ziel zu überschreiben.
Sie sagen, dass sie den Namespace der Klasse verschmutzen, aber das ist nicht der Kompromiss, den Sie beim Faktorisieren Ihres Codes berücksichtigen müssen. Ein zukünftiger Leser der Klasse (z. B. Sie) fragt viel häufiger: "Was macht diese spezielle Methode und wie muss ich sie ändern, damit sie das tut, was die geänderten Anforderungen aussagen?" als "Was ist der Zweck und das Gefühl, alle Methoden in der Klasse zu sein? " Daher ist es viel wichtiger, jede der Methoden verständlicher zu machen (indem sie weniger Elemente enthält), als die gesamte Klasse verständlicher zu machen (indem es weniger Methoden hat).
Wenn die Aufgaben nicht wirklich in sich geschlossen sind, sondern einige Statusvariablen erfordern, um sich zu bewegen, kann stattdessen ein Methodenobjekt, ein Hilfsobjekt oder ein ähnliches Konstrukt die richtige Wahl sein. Und wenn die Aufgaben völlig eigenständig sind und überhaupt nicht an die Anwendungsdomäne gebunden sind (z. B. nur die Formatierung von Zeichenfolgen, sollten sie möglicherweise in eine ganz andere (Dienstprogramm-) Klasse fallen. Aber das ändert nichts an der Tatsache, dass " Methoden pro Klasse niedrig zu halten "ist bestenfalls ein sehr untergeordnetes Ziel.
quelle
Ich mag keinen Ansatz. Sie haben keinen breiteren Kontext angegeben, aber meistens sieht es so aus:
Sie haben eine Klasse, die einige Aufgaben erledigt, indem sie die Leistung mehrerer Dienste in einem einzigen Ergebnis kombiniert.
Jeder Ihrer Dienste implementiert nur einen Teil der Logik. Etwas Besonderes, das nur dieser Service leisten kann. Wenn es andere private Methoden als nur solche gibt, die die Haupt-API unterstützen, so dass Sie sie einfach sortieren können und es sowieso nicht zu viele davon geben sollte.
Das Fazit lautet: Wenn Sie Regionen in Ihrem Code erstellen, um Methoden zu gruppieren, ist es an der Zeit, über die Kapselung ihrer Logik mit einem neuen Dienst nachzudenken.
quelle
Das Problem beim Erstellen von Funktionen innerhalb der Methode besteht darin, dass die Länge der Methode nicht verringert wird.
Wenn Sie die zusätzliche Schutzstufe "Private to Method" wünschen, können Sie eine neue Klasse erstellen
Aber Klassen in Klassen sind sehr hässlich: /
quelle
Es wird empfohlen, den Umfang von Sprachkonstrukten wie Variablen und Methoden zu minimieren. Vermeiden Sie beispielsweise globale Variablen. Dies erleichtert das Verständnis des Codes und hilft, Missbrauch zu vermeiden, da auf das Konstrukt an weniger Stellen zugegriffen werden kann.
Dies spricht für die Verwendung der lokalen Funktionen.
quelle
Ich würde zustimmen, dass lange Methoden oft ein Codegeruch sind, aber ich denke nicht, dass das das ganze Bild ist, sondern dass die Methode lang ist, was auf ein Problem hinweist. Meine allgemeine Regel lautet: Wenn der Code mehrere unterschiedliche Aufgaben ausführt, sollte jede dieser Aufgaben eine eigene Methode sein. Für mich ist es wichtig, ob sich diese Codeabschnitte wiederholen oder nicht. es sei denn, Sie sind sich wirklich absolut sicher, dass niemand diese in Zukunft einzeln einzeln aufrufen möchte (und das ist sehr schwer zu sagen!), setzen Sie sie in eine andere Methode (und machen Sie sie privat - was ein sehr starker Indikator sein sollte Sie erwarten nicht, dass es außerhalb der Klasse verwendet wird.
Ich muss gestehen, dass ich noch keine lokalen Funktionen verwendet habe, daher ist mein Verständnis hier noch lange nicht vollständig, aber der von Ihnen angegebene Link legt nahe, dass sie häufig ähnlich wie ein Lambda-Ausdruck verwendet werden (obwohl es sich hier um eine Reihe von Anwendungsfällen handelt wo sie möglicherweise geeigneter sind als Lambdas oder wo Sie kein Lambda verwenden können, siehe Lokale Funktionen im Vergleich zu Lambda-Ausdrücken für Einzelheiten). Hier könnte es also an der Granularität der "anderen" Aufgaben liegen; Wenn sie ziemlich trivial sind, wäre dann vielleicht eine lokale Funktion in Ordnung? Andererseits habe ich Beispiele für gigantische Lambda-Ausdrücke gesehen (wahrscheinlich, bei denen ein Entwickler kürzlich LINQ entdeckt hat), die den Code weitaus weniger verständlich und wartbar gemacht haben, als wenn er einfach von einer anderen Methode aufgerufen worden wäre.
Auf der Seite Lokale Funktionen heißt es:
Ich bin mir nicht sicher, ob ich wirklich mit MS als Grund für die Verwendung bin. Der Umfang Ihrer Methode (zusammen mit ihrem Namen und ihren Kommentaren) sollte klar machen, was Ihre Absicht zu diesem Zeitpunkt war . Mit einer lokalen Funktion konnte ich sehen, dass andere Entwickler dies als sakrosankter ansehen, aber möglicherweise bis zu dem Punkt, an dem sie, wenn in Zukunft eine Änderung eintritt, die die Wiederverwendung dieser Funktionalität erfordert, ihre eigene Prozedur schreiben und die lokale Funktion beibehalten ;; Dadurch wird ein Problem mit der Codeduplizierung erstellt. Der letztere Satz aus dem obigen Zitat könnte relevant sein, wenn Sie den Teammitgliedern nicht vertrauen, dass sie eine private Methode verstehen, bevor Sie sie aufrufen, und sie daher unangemessen aufrufen (Ihre Entscheidung könnte davon betroffen sein, obwohl Bildung hier eine bessere Option wäre). .
Zusammenfassend würde ich es im Allgemeinen vorziehen, in Methoden aufzuteilen, aber MS hat aus einem bestimmten Grund lokale Funktionen geschrieben, daher würde ich sicherlich nicht sagen, dass sie nicht verwendet werden.
quelle