webentwicklung-frage-antwort-db.com.de

Wie viele Parameter sind zu viele?

Routinen können Parameter haben, das ist keine Neuigkeit. Sie können beliebig viele Parameter definieren, aber zu viele machen es schwierig, Ihre Routine zu verstehen und zu pflegen.

Natürlich können Sie eine strukturierte Variable als Problemumgehung verwenden: Setzen Sie alle diese Variablen in eine einzige Struktur und übergeben Sie sie an die Routine. Tatsächlich ist die Verwendung von Strukturen zur Vereinfachung von Parameterlisten eine der Techniken, die Steve McConnell in Code Complete beschrieben hat. Aber wie er sagt:

Sorgfältige Programmierer vermeiden es, Daten mehr zu bündeln, als es logischerweise erforderlich ist.

Wenn Ihre Routine also zu viele Parameter enthält oder Sie eine Struktur verwenden, um eine große Parameterliste zu verschleiern, tun Sie wahrscheinlich etwas Falsches. Das heißt, Sie halten die Kupplung nicht locker.

Meine Frage ist: Wann kann ich eine Parameterliste als zu groß betrachten? Ich denke, dass mehr als 5 Parameter zu viele sind. Was denkst du?

228
Auron

Wann gilt etwas als so obszön, dass es trotz der Garantie der ersten Novelle auf freie Meinungsäußerung reguliert werden kann? Laut Justice Potter Stewart "weiß ich es, wenn ich es sehe." Das gilt auch hier.

Ich hasse es, solche harten und schnellen Regeln zu machen, weil sich die Antwort nicht nur in Abhängigkeit von der Größe und dem Umfang Ihres Projekts ändert, sondern ich denke, sie ändert sich sogar bis auf Modulebene. Abhängig davon, was Ihre Methode tut oder was die Klasse darstellen soll, ist es durchaus möglich, dass 2 Argumente zu viele sind und ein Symptom für zu viel Kopplung darstellen.

Ich würde vorschlagen, dass Sie das alles wirklich wissen, indem Sie die Frage an erster Stelle stellen und Ihre Frage genauso einschränken wie Sie. Die beste Lösung besteht darin, sich nicht auf eine feste und schnelle Zahl zu verlassen, sondern sich auf Entwurfsprüfungen und Codeprüfungen unter Ihren Kollegen zu konzentrieren, um Bereiche mit geringer Kohäsion und enger Kopplung zu identifizieren.

Haben Sie keine Angst, Ihren Kollegen Ihre Arbeit zu zeigen. Wenn Sie Angst haben, ist das wahrscheinlich das größere Zeichen dafür, dass etwas mit Ihrem Code nicht stimmt und dass Sie wissen es bereits.

162
Nick

Eine Funktion kann nur zu viele Parameter haben, wenn einige der Parameter redundant sind. Wenn alle Parameter verwendet werden, muss die Funktion die richtige Anzahl von Parametern haben. Nehmen Sie diese häufig verwendete Funktion:

HWND CreateWindowEx
(
  DWORD dwExStyle,
  LPCTSTR lpClassName,
  LPCTSTR lpWindowName,
  DWORD dwStyle,
  int x,
  int y,
  int nWidth,
  int nHeight,
  HWND hWndParent,
  HMENU hMenu,
  HINSTANCE hInstance,
  LPVOID lpParam
);

Das sind 12 Parameter (9, wenn Sie x, y, w und h als Rechteck bündeln) und es gibt auch die vom Klassennamen abgeleiteten Parameter. Wie würden Sie das reduzieren? Möchten Sie die Anzahl auf den Punkt reduzieren?

Lassen Sie sich nicht von der Anzahl der Parameter stören, sondern stellen Sie sicher, dass diese logisch und gut dokumentiert sind, und lassen Sie sich von Intellisense leiten* dir helfen.

* Andere Codierungsassistenten sind verfügbar!

124
Skizz

In Clean Code widmete Robert C. Martin dem Thema vier Seiten. Hier ist der Kern:

Die ideale Anzahl von Argumenten für eine Funktion ist Null (Null). Als nächstes kommt eins (monadisch), dicht gefolgt von zwei (dyadisch). Drei Argumente (Triade) sollten nach Möglichkeit vermieden werden. Mehr als drei (polyadisch) erfordern eine besondere Begründung - und sollten dann sowieso nicht verwendet werden.

106

Einige Codes, mit denen ich in der Vergangenheit gearbeitet habe, verwendeten globale Variablen, um zu vermeiden, dass zu viele Parameter herumgereicht werden.

Bitte tu das nicht!

(Meistens.)

79

Wenn Sie anfangen, die Parameter in der Signatur mental abzählen und sie dem Aufruf zuordnen zu müssen, ist es Zeit für eine Umgestaltung!

38
Rob Walker

Vielen Dank für all Ihre Antworten:

  • Es war ein bisschen überraschend, Leute zu finden, die ebenfalls (wie ich) der Meinung sind, dass 5 Parameter eine gute Grenze für die Vernunft des Codes darstellen.

  • Im Allgemeinen sind sich die Leute einig, dass ein Grenzwert zwischen 3 und 4 eine gute Faustregel ist. Dies ist vernünftig, da die Leute normalerweise eine schlechte Zeit haben, wenn sie mehr als 4 Dinge zählen.

  • Wie Milan points können Menschen im Durchschnitt mehr oder weniger 7 Dinge gleichzeitig im Kopf behalten. Aber ich denke, Sie können nicht vergessen, dass Sie beim Entwerfen/Aufrechterhalten/Studieren einer Routine mehr als nur die Parameter im Auge behalten müssen.

  • Einige Leute denken, dass eine Routine so viele Argumente haben sollte, wie sie muss. Ich bin damit einverstanden, aber nur für einige bestimmte Fälle (Aufrufe von OS-APIs, Routinen, bei denen die Optimierung wichtig ist, usw.). Ich schlage vor, die Komplexität dieser Routinen zu verbergen, indem Sie nach Möglichkeit eine Abstraktionsebene direkt über diesen Aufrufen hinzufügen.

  • Nick hat einige interessante Gedanken dazu. Wenn Sie seine Kommentare nicht lesen möchten, fasse ich für Sie zusammen: Auf den Punkt gebracht, kommt es darauf an :

    Ich hasse es, solche harten und schnellen Regeln zu machen, weil sich die Antwort nicht nur in Abhängigkeit von der Größe und dem Umfang Ihres Projekts ändert, sondern ich denke, sie ändert sich sogar bis auf Modulebene. Abhängig davon, was Ihre Methode tut oder was die Klasse darstellen soll, ist es durchaus möglich, dass 2 Argumente zu viele sind und ein Symptom für zu viel Kopplung darstellen.

    Die Moral hier ist, keine Angst davor zu haben, Ihren Kollegen Ihren Code zu zeigen, mit ihnen zu diskutieren und zu versuchen, "Bereiche zu identifizieren, in denen Sie einen geringen Zusammenhalt und eine enge Kopplung haben".

  • Schließlich denke ich, wnoise stimmt sehr mit Nick überein und schließt seinen satirischen Beitrag mit diese poetische Vision (siehe Kommentare unten) von die kunst des programmierens:

    Programmierung ist kein Engineering. Die Organisation von Code ist eine Kunst, weil sie von menschlichen Faktoren abhängt, die für eine harte Regel zu stark vom Kontext abhängen.

31
Auron

Diese Antwort geht von einer OO Sprache aus. Wenn Sie keine verwenden - überspringen Sie diese Antwort (mit anderen Worten, dies ist keine ganz sprachunabhängige Antwort).

Wenn Sie mehr als 3 Parameter übergeben (insbesondere intrinsische Typen/Objekte), ist dies nicht "Zu viele", sondern es fehlt möglicherweise die Möglichkeit, ein neues Objekt zu erstellen.

Suchen Sie nach Gruppen von Parametern, die an mehr als eine Methode übergeben werden - selbst eine Gruppe, die an zwei Methoden übergeben wird, garantiert fast, dass Sie ein neues Objekt dort haben sollten.

Dann überarbeiten Sie die Funktionalität in Ihr neues Objekt und Sie werden nicht glauben, wie sehr dies sowohl Ihrem Code als auch Ihrem Verständnis von OO Programmierung) hilft.

16
Bill K

Es scheint, als gäbe es andere Überlegungen als bloße Zahlen. Hier sind einige, die mir in den Sinn kommen:

  1. logische Beziehung zum primären Zweck der Funktion gegenüber einmaligen Einstellungen

  2. Wenn es sich nur um Umgebungsflags handelt, kann das Bündeln sehr praktisch sein

13
John Mulder

In einem der bekannten Programmierepigramme von Alan Perlis (ACM SIGPLAN Notices 17 (9), September 1982) heißt es: "Wenn Sie eine Prozedur mit 10 Parametern haben, haben Sie wahrscheinlich einige verpasst."

12
Peter S. Housel

Laut Steve McConnell in Code Complete sollten Sie

Begrenzen Sie die Anzahl der Parameter einer Routine auf ungefähr sieben

11
Paul Reiners

Wenn die Liste in meiner IDE eine Zeile überschreitet, ist es für mich ein Parameter zu viel. Ich möchte alle Parameter in einer Zeile sehen, ohne den Augenkontakt zu unterbrechen. Aber das ist nur meine persönliche Präferenz.

9
Learning

Ich stimme jedoch im Allgemeinen mit 5 überein, wenn es eine Situation gibt, in der ich mehr benötige und es der klarste Weg ist, das Problem zu lösen, würde ich mehr verwenden.

9
Inisheer

Sieben Dinge im Kurzzeitgedächtnis?

  1. Name der Funktion
  2. Rückgabewert der Funktion
  3. Zweck der Funktion
  4. Parameter 1
  5. Parameter 2
  6. Parameter 3
  7. Parameter 4
8
Mike Clark

Aktivieren Sie in Worst 5 Code Snippets das zweite Kontrollkästchen "Ist dies ein Konstruktor?". Es hat wie über 37 ⋅ 4 ≈ 150 parameter:

Hier hat ein Programmierer diesen Konstruktor geschrieben. [...] Einige von Ihnen denken vielleicht, dass es sich um einen großen Konstruktor handelt, aber er verwendete Eclipse-Tools zur automatischen Codegenerierung Schliessen Sie, dass dieser Konstruktor von Hand geschrieben wurde. (Übrigens ist dies nur der obere Teil des Konstruktors, nicht vollständig).

constructor with over 150 parameters

7
medopal

Einer mehr als nötig. Ich will nicht glib sein, aber es gibt einige Funktionen, die unbedingt einige Optionen benötigen. Beispielsweise:

void *
mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t offset);

Es gibt 6 Argumente, und jedes von ihnen ist von wesentlicher Bedeutung. Darüber hinaus gibt es keine gemeinsame Verbindung zwischen ihnen, die eine Bündelung rechtfertigt. Vielleicht könnten Sie "struct mmapargs" definieren, aber das wäre schlimmer.

6
Kirk Strauser

Laut Perl Best Practices ist 3 in Ordnung, 4 zu viele. Es ist nur eine Richtlinie, aber in unserem Shop versuchen wir, uns daran zu halten.

5
Adam Bellaire

97 klingt genau richtig.

Weniger und Sie verlieren an Flexibilität.

5
Johan

Eine verwandte Frage, die Sie berücksichtigen sollten, ist, wie zusammenhängend die Routine ist. Eine große Anzahl von Parametern kann ein Geruch sein, der Ihnen sagt, dass die Routine selbst versucht, zu viel zu tun, und daher ist ihre Kohäsion verdächtig. Ich stimme zu, dass eine feste und schnelle Anzahl von Parametern wahrscheinlich unmöglich ist, aber ich würde vermuten, dass eine Routine mit hoher Kohäsion eine geringe Anzahl von Parametern implizieren würde.

5

Ich würde die Grenze für öffentliche Funktionen bei 5 Parametern selbst ziehen.

IMHO, lange Parameterlisten sind nur in privaten/lokalen Hilfsfunktionen zulässig, die nur von wenigen bestimmten Stellen im Code aufgerufen werden sollen. In diesen Fällen müssen Sie möglicherweise viele Statusinformationen weitergeben, aber die Lesbarkeit ist nicht so wichtig, da nur Sie (oder jemand, der Ihren Code verwaltet und die Grundlagen Ihres Moduls versteht) sich darum kümmern müssen Aufruf dieser Funktion.

5
Kip

Unter dem Gesichtspunkt der Leistung möchte ich darauf hinweisen, dass die Übergabe vieler Parameter nach Wert das Programm verlangsamt, je nachdem, wie Sie Parameter an eine Methode übergeben, da jeder Parameter kopiert und dann auf den Stapel gelegt werden muss.

Die Verwendung einer einzelnen Klasse zum Einschließen aller Parameter funktioniert besser, da ein einzelner Parameter, der als Referenz übergeben wird, elegant, sauber und schneller ist!

4

Als Faustregel halte ich bei drei Parametern an. Immer mehr und es ist an der Zeit, stattdessen ein Array von Parametern oder ein Konfigurationsobjekt zu übergeben, wodurch auch zukünftige Parameter hinzugefügt werden können, ohne die API zu ändern.

4
Eran Galperin

Eine Längenbeschränkung für eine Parameterliste ist nur eine weitere Einschränkung. Und Einschränkung bedeutet angewandte Gewalt. Es klingt lustig, aber Sie können auch beim Programmieren gewaltfrei sein. Lass einfach den Code die Regeln diktieren. Wenn Sie über viele Parameter verfügen, ist der Rumpf der Funktions-/Klassenmethode offensichtlich groß genug, um sie zu verwenden. Und große Code-Schnipsel können normalerweise überarbeitet und in kleinere Teile aufgeteilt werden. Sie erhalten also eine Lösung gegen das Vorhandensein vieler Parameter als kostenlosen Bonus, da diese auf die kleineren überarbeiteten Codeteile aufgeteilt sind.

4
Anonymous

Meiner Meinung nach könnte es Fälle geben, in denen Sie 4 oder eine feste Anzahl überschreiten. Dinge, auf die man achten könnte

  1. Ihre Methode tut zu viel und Sie müssen umgestalten.
  2. Möglicherweise möchten Sie eine Sammlung oder eine Datenstruktur verwenden.
  3. Überdenken Sie Ihr Klassendesign, vielleicht müssen einige Dinge nicht weitergegeben werden.

Unter dem Gesichtspunkt der Benutzerfreundlichkeit oder des einfachen Lesens von Code denke ich, wenn Sie Ihre Methodensignatur irgendwie in "Word Wrap" umbrechen müssen, sollten Sie innehalten und nachdenken, es sei denn, Sie fühlen sich hilflos und alle Bemühungen, die Signatur zu verkleinern, führen zu kein Ergebnis. Einige sehr gute Bibliotheken in der Vergangenheit und Gegenwart verwenden mehr als 4-5 Kinderwagen.

3
Perpetualcoder

Meine Faustregel ist, dass ich mir die Parameter lange genug merken muss, um einen Anruf zu betrachten und zu erklären, was er tut. Wenn ich mir also die Methode nicht ansehen und dann zu einem Methodenaufruf übergehen kann und mir überlege, welcher Parameter was macht, dann gibt es zu viele.

Für mich entspricht das ungefähr 5, aber ich bin nicht so klug. Ihr Kilometerstand kann variieren.

Sie können ein Objekt mit Eigenschaften zum Speichern der Parameter erstellen und diese übergeben, wenn Sie einen von Ihnen festgelegten Grenzwert überschreiten. Siehe das Buch Refactoring von Martin Fowler und das Kapitel zur Vereinfachung von Methodenaufrufen.

3
Mike Two

Ich stimme mit Robert Martins Zitat in Clean Code überein ( wie oben zitiert ): Je weniger Parameter, desto besser. Mehr als 5-7 Parameter und Methodenaufrufe sind ziemlich schwer zu verstehen. Besonders schlimm wird es, wenn einige der Parameter optional sind (und daher Nullwerte annehmen) oder wenn alle Parameter denselben Typ haben (was es noch schwieriger macht, herauszufinden, welcher Parameter welcher ist). Wenn Sie Parameter in zusammenhängende Domänenobjekte wie Customer und Account bündeln können, ist die Arbeit mit Ihrem Code wesentlich angenehmer.

Es gibt einen Edge-Fall: Wenn Sie einen Methodenaufruf haben, der eine variable Anzahl von Parametern akzeptiert, die eine logische Menge bilden , gibt es weniger kognitiven Overhead mit mehr Parametern . Beispielsweise benötigen Sie möglicherweise eine Methode, die die Anzahl der HTTP-Anforderungswiederholungen in Millisekunden zwischen den Wiederholungen angibt. Drei Wiederholungsversuche in Intervallen von 1s, 2s und 3s können wie folgt angegeben werden:

retries(1000, 2000, 3000)

In diesem begrenzten Fall erhöht das Hinzufügen weiterer Parameter zu einem Anruf die mentale Überlastung nicht so sehr.

Eine weitere Überlegung ist, ob Ihre Sprache benannte Parameterlisten unterstützt und Sie optionale Parameter weglassen können. Größere benannte Parameterlisten sind leichter zu verstehen als größere unbenannte Parameterlisten.

Aber ich würde mich immer noch eher auf weniger als auf mehr Parameter beschränken.

1
Jim Ferrans

Wenn ich 7-10 Parameter in einer Routine habe, schaue ich, wie ich sie in eine neue Klasse bündle aber nicht, wenn diese Klasse nichts anderes als eine Reihe von Feldern mit Gettern und Setzern wäre - die neue Klasse muss mache etwas anderes als Werte rein und raus zu mischen. Ansonsten würde ich mich lieber mit der langen Parameterliste abfinden.

1
finnw

Ich würde meine Antwort darauf stützen, wie oft die Funktion aufgerufen wird.

Wenn es sich um eine Init-Funktion handelt, die immer nur einmal aufgerufen wird, lassen Sie es 10 oder mehr Parameter dauern, wen interessiert das?.

Wenn es mehrere Male pro Frame heißt, dann neige ich dazu, eine Struktur zu erstellen und nur einen Zeiger darauf zu übergeben, da dies tendenziell schneller ist (vorausgesetzt, Sie erstellen die Struktur nicht jedes Mal neu).

1
KPexEA

Dies hängt stark von der Umgebung ab, in der Sie arbeiten. Nehmen Sie zum Beispiel Javascript. In Javascript werden Parameter am besten über Objekte mit Schlüssel/Wert-Paaren übergeben. In der Praxis bedeutet dies, dass Sie nur einen Parameter haben. In anderen Systemen liegt der Sweet Spot bei drei oder vier.

Am Ende läuft alles auf den persönlichen Geschmack hinaus.

1
Joeri Sebrechts

Ich bin damit einverstanden, dass 3 in Ordnung ist, 4 als Richtlinie zu viele. Mit mehr als 3 Parametern erledigen Sie zwangsläufig mehr als eine Aufgabe. Mehr als eine Aufgabe sollte in separate Methoden aufgeteilt werden.

Wenn ich mir jedoch das neueste Projekt anschaue, an dem ich gearbeitet habe, gibt es zahlreiche Ausnahmen, und in den meisten Fällen ist es schwierig, auf drei Parameter zu kommen.

1
kae

Nach Jeff Bezos von Amazon Ruhm kann nicht mehr als mit zwei Pizzen gefüttert werden:

1
Kevin Pang

Es ist bekannt, dass Menschen im Durchschnitt 7 +/- 2 Dinge gleichzeitig im Kopf behalten können. Ich verwende dieses Prinzip gerne mit Parametern. Unter der Annahme, dass alle Programmierer überdurchschnittlich intelligente Menschen sind, würde ich sagen, dass 10+ zu viele sind.

Übrigens, wenn Parameter in irgendeiner Weise ähnlich sind, würde ich sie eher in einen Vektor oder eine Liste als in eine Struktur oder eine Klasse einfügen.

1
Milan Babuškov

IMO, die Rechtfertigung für eine lange Parameterliste ist, dass die Daten oder der Kontext dynamischer Natur sind, denken Sie an printf (); ein gutes beispiel für die verwendung von varargs. Eine bessere Möglichkeit, solche Fälle zu behandeln, besteht darin, einen Stream oder eine XML-Struktur zu übergeben. Dadurch wird wiederum die Anzahl der Parameter minimiert.

Einer Maschine würde sicherlich eine große Anzahl von Argumenten nichts ausmachen, aber die Entwickler berücksichtigen auch den Wartungsaufwand, die Anzahl der Einzeltestfälle und Validierungsprüfungen. Designer hassen auch lange Argumentlisten, mehr Argumente bedeuten mehr Änderungen an den Schnittstellendefinitionen, wann immer eine Änderung vorgenommen werden soll. Die Fragen zur Kopplung/Kohäsion ergeben sich aus den oben genannten Aspekten.

0
questzen

Ich würde sagen, solange du Überladungen hast, die 2-4 haben, bist du gut darin, höher zu steigen, wenn du es brauchst.

0
Chad Moran

Ich denke, die tatsächliche Anzahl hängt wirklich davon ab, was mit dem Kontext der Funktion logisch sinnvoll ist. Ich bin damit einverstanden, dass ungefähr 4-5 Parameter überfüllt werden.

Wenn Sie Flags setzen, können Sie diese Situation am besten umgehen, indem Sie die Werte und OR zusammen aufzählen.

0
Jordan Parmer