it-swarm.com.de

Techniken zum Minimieren der Anzahl von Funktionsargumenten

In Clean Code steht geschrieben, dass "die ideale Anzahl von Argumenten für eine Funktion Null ist". Die Gründe dafür werden erklärt und sind sinnvoll. Was ich suche, sind Techniken zum Refaktorieren von Methoden mit 4 oder mehr Argumenten, um dieses Problem zu lösen.

Eine Möglichkeit besteht darin, die Argumente in eine neue Klasse zu extrahieren, aber das würde sicherlich zu einer Explosion von Klassen führen? Und diese Klassen werden wahrscheinlich Namen haben, die gegen einige der Namensregeln verstoßen (die mit "Daten" oder "Info" usw. enden)?

Eine andere Technik besteht darin, Variablen, die von mehreren Funktionen verwendet werden, zu einer privaten Mitgliedsvariablen zu machen, um deren Übergabe zu vermeiden. Dies erweitert jedoch den Umfang der Variablen, möglicherweise so, dass sie für Funktionen offen ist, die sie nicht wirklich benötigen.

Ich suche nur nach Möglichkeiten, um Funktionsargumente zu minimieren, nachdem ich die Gründe akzeptiert habe, warum dies eine gute Idee ist.

13
Neil Barnwell

Das Wichtigste ist, dass dies Richtlinien sind, keine Regeln.

Es gibt Fälle, in denen eine Methode einfach muss ein Argument annimmt. Denken Sie an die + Methode zum Beispiel für Zahlen. Oder die add -Methode für eine Sammlung.

In der Tat könnte man sogar argumentieren, dass das, was es bedeutet, zwei Zahlen hinzuzufügen, vom Kontext abhängt, z. in ℤ 3 + 3 == 6, aber in ℤ| 5 3 + 3 == 2, also sollte der Additionsoperator wirklich eine Methode für ein Kontextobjekt sein, das zwei Argumente anstelle einer Methode für Zahlen mit einem Argument akzeptiert.

Ebenso muss eine Methode zum Vergleichen von zwei Objekten entweder eine Methode sein, bei der ein Objekt das andere als Argument verwendet, oder eine Methode des Kontexts, bei der zwei Objekte als Argumente verwendet werden. Daher ist es einfach nicht sinnvoll, eine Vergleichsmethode zu verwenden weniger als ein Argument.

Es gibt jedoch einige Möglichkeiten, um die Anzahl der Argumente für eine Methode zu verringern:

  • Verkleinern Sie die Methode selbst: Wenn die Methode so viele Argumente benötigt, tut sie möglicherweise zu viel?
  • Eine fehlende Abstraktion: Wenn die Argumente eng miteinander korrelieren, gehören sie möglicherweise zusammen und es fehlt Ihnen eine Abstraktion? (Beispiel für ein kanonisches Lehrbuch: Übergeben Sie anstelle von zwei Koordinaten ein Point -Objekt, oder übergeben Sie anstelle von Benutzername und E-Mail ein IdCard -Objekt.)
  • Objektstatus: Wenn das Argument von mehreren Methoden benötigt wird, sollte es möglicherweise Teil des Objektstatus sein. Wenn es nur von einigen Methoden benötigt wird, von anderen jedoch nicht, macht das Objekt möglicherweise zu viel und sollte eigentlich zwei Objekte sein.

Eine Möglichkeit besteht darin, die Argumente in eine neue Klasse zu extrahieren, aber das würde sicherlich zu einer Explosion von Klassen führen?

Wenn Ihr Domain-Modell viele verschiedene Arten von Dingen enthält, enthält Ihr Code viele verschiedene Arten von Objekten. Daran ist nichts auszusetzen.

Und diese Klassen werden wahrscheinlich Namen haben, die gegen einige der Namensregeln verstoßen (die mit "Daten" oder "Info" usw. enden)?

Wenn Sie keinen richtigen Namen finden, haben Sie möglicherweise entweder zu viele oder zu wenige Argumente zusammengefasst. Sie haben also entweder nur ein Fragment einer Klasse oder Sie haben mehr als eine Klasse.

Eine andere Technik besteht darin, Variablen, die von mehreren Funktionen verwendet werden, zu einer privaten Mitgliedsvariablen zu machen, um deren Übergabe zu vermeiden. Dies erweitert jedoch den Umfang der Variablen, möglicherweise so, dass sie für Funktionen offen ist, die sie nicht wirklich benötigen.

Wenn Sie eine Gruppe von Methoden haben, die alle mit denselben Argumenten arbeiten, und eine andere Gruppe von Methoden, die dies nicht tun, gehören sie möglicherweise zu verschiedenen Klassen.

Beachten Sie, wie oft ich das Wort "vielleicht" verwendet habe? Deshalb sind das Richtlinien, keine Regeln. Vielleicht ist Ihre Methode mit 4 Parametern vollkommen in Ordnung!

16
Jörg W Mittag

Beachten Sie, dass Nullargumente keine Nebenwirkungen implizieren, da Ihr Objekt ein implizites Argument ist. Schauen Sie sich zum Beispiel an, wie viele Zero-Arity-Methoden Scalas unveränderliche Liste hat.

Eine nützliche Technik nenne ich die "Linsenfokussierung". Wenn Sie ein Kameraobjektiv fokussieren, ist es einfacher, den wahren Fokuspunkt zu erkennen, wenn Sie zu weit gehen, und ihn dann auf den richtigen Punkt zurückzusetzen. Gleiches gilt für das Software-Refactoring.

Insbesondere wenn Sie die verteilte Versionskontrolle verwenden, können Sie leicht mit Softwareänderungen experimentieren, prüfen, ob Ihnen das Aussehen gefällt, und sich zurückziehen, wenn Sie dies nicht tun. Aus irgendeinem Grund scheinen die Benutzer dies jedoch nur ungern zu tun.

Im Kontext Ihrer aktuellen Frage bedeutet dies, dass Sie die Versionen mit null oder einem Argument schreiben, wobei zuerst mehrere abgespaltene Funktionen verwendet werden. Dann ist es relativ einfach zu erkennen, welche Funktionen zur besseren Lesbarkeit kombiniert werden müssen.

Beachten Sie, dass der Autor auch ein großer Befürworter der testgetriebenen Entwicklung ist, die zu Beginn tendenziell Funktionen mit geringer Arität erzeugt, da Sie mit Ihren trivialen Testfällen beginnen.

6
Karl Bielefeldt

Ein Ansatz, der einfach (und naiv - oder sollte ich sogar sagen blind) nur darauf abzielt, die Anzahl der Argumente auf Funktionen zu reduzieren, ist wahrscheinlich falsch. Es ist absolut nichts Falsches an Funktionen mit einer großen Anzahl von Argumenten. Wenn sie von der Logik benötigt werden, sind sie auch erforderlich ... Eine lange Parameterliste macht mir überhaupt keine Sorgen - solange sie zur besseren Lesbarkeit richtig formatiert und kommentiert ist.

Für den Fall, dass alle oder eine Teilmenge von Argumenten zu einer eindeutigen logischen Entität gehören und üblicherweise in Gruppen im gesamten Programm herumgereicht werden, ist es möglicherweise sinnvoll, sie in einem Container zu gruppieren - normalerweise in einer Struktur oder einer anderen Objekt. Typische Beispiele könnten eine Art Nachricht oder Ereignis Datentyp sein.

Sie können diesen Ansatz leicht übertreiben. Wenn Sie feststellen, dass das Ein- und Auspacken von Material zu und von solchen Transportbehältern mehr Aufwand verursacht als die Lesbarkeit verbessert, sind Sie wahrscheinlich zu weit gegangen.

OTOH, große Parameterlisten können ein Zeichen dafür sein, dass Ihr Programm möglicherweise nicht richtig strukturiert ist - möglicherweise die Funktion, die eine so große Anzahl von Parametern erfordert versucht nur zu viel zu tun und sollte in mehrere kleinere aufgeteilt werden Funktionen. Ich fange lieber hier an, als mir Gedanken über die Anzahl der Parameter zu machen.

0
tofro

Es gibt keinen magischen Weg: Sie müssen die Problemdomäne beherrschen, um die richtige Architektur zu finden. Dies ist der einzige Weg zum Refactor: Beherrschen der Problemdomäne. Mehr als vier Parameter sind nur eine sichere Wette, dass Ihre aktuelle Architektur fehlerhaft und falsch ist.

Die einzigen Ausnahmen sind Compiler (Metaprogramme) und Simulationen, bei denen die Grenze theoretisch 8, aber wahrscheinlich nur 5 beträgt.

0
theDoctor