Routinen können Parameter haben, das sind keine Neuigkeiten. Sie können so viele Parameter definieren, wie Sie benötigen, aber zu viele davon erschweren das Verständnis und die Wartung Ihrer Routine.
Natürlich können Sie eine strukturierte Variable als Problemumgehung verwenden: Fügen Sie alle diese Variablen in eine einzige Struktur ein 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 das Bündeln von Daten mehr als logisch notwendig.
Wenn Ihre Routine also zu viele Parameter enthält oder Sie eine Struktur verwenden, um eine große Parameterliste zu verschleiern, machen Sie wahrscheinlich etwas falsch. Das heißt, Sie halten die Kupplung nicht locker.
Meine Frage ist, wann ich eine Parameterliste als zu groß betrachten kann. Ich denke, dass mehr als 5 Parameter zu viele sind. Was denken Sie?
Antworten:
Wann wird etwas als so obszön angesehen, dass es trotz der Garantie der 1. Änderung der Redefreiheit 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 erstellen, weil sich die Antwort nicht nur abhängig von der Größe und dem Umfang Ihres Projekts ändert, sondern ich denke, dass sie sich sogar bis auf Modulebene ändert. 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 sind.
Ich würde vorschlagen, dass Sie all dies wirklich wissen, indem Sie die Frage an erster Stelle stellen und Ihre Frage genauso qualifizieren wie Sie. Die beste Lösung besteht darin, sich nicht auf eine feste Zahl zu verlassen, sondern sich stattdessen auf Entwurfsprüfungen und Codeprüfungen unter Ihren Kollegen zu konzentrieren, um Bereiche zu identifizieren, in denen Sie eine geringe Kohäsion und eine enge Kopplung aufweisen.
Haben Sie niemals Angst, Ihren Kollegen Ihre Arbeit zu zeigen. Wenn Sie Angst haben, ist dies wahrscheinlich das größere Zeichen dafür, dass etwas mit Ihrem Code nicht stimmt und dass Sie es bereits kennen .
quelle
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:
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 mehr auf den Punkt reduzieren?
Lassen Sie sich nicht von der Anzahl der Parameter stören, stellen Sie nur sicher, dass diese logisch und gut dokumentiert sind, und lassen Sie sich von Intellisense * helfen.
* Andere Codierungsassistenten sind verfügbar!
quelle
In Clean Code widmete Robert C. Martin dem Thema vier Seiten. Hier ist das Wesentliche:
quelle
<algorithm>
würde, würde es auf ein Bereichsobjekt wirken. Sammlungen wären Bereiche, aber nicht alle Bereiche wären Sammlungen. Und tatsächlich hat Boost das bereits getan. Mein Punkt ist jedenfalls, dass eine massiv genutzte Bibliothek diesen Rat ignoriert. Das Schlimmste, was Ihnen garantiert passiert, wenn Sie dies auch tun, ist, dass viele Ihrer Millionen Benutzer mit geringfügigen Vereinfachungen an Ihrer Benutzeroberfläche basteln ;-)Einige Codes, mit denen ich in der Vergangenheit gearbeitet habe, verwendeten globale Variablen, um zu vermeiden, dass zu viele Parameter weitergegeben werden.
Bitte tu das nicht!
(Normalerweise.)
quelle
Wenn Sie anfangen müssen, die Parameter in der Signatur mental abzuzählen und sie dem Anruf zuzuordnen, ist es Zeit für eine Umgestaltung!
quelle
Vielen Dank für all Ihre Antworten:
Es war ein bisschen überraschend, Leute zu finden, die (wie ich) auch denken, dass 5 Parameter eine gute Grenze für die Vernunft des Codes sind.
Im Allgemeinen sind sich die Leute einig, dass ein Grenzwert zwischen 3 und 4 eine gute Faustregel ist. Dies ist vernünftig, da Menschen normalerweise eine schlechte Zeit haben, mehr als 4 Dinge zu zählen.
Wie Milan betont , können Menschen im Durchschnitt mehr oder weniger 7 Dinge gleichzeitig im Kopf behalten. Aber ich denke, dass Sie nicht vergessen können, dass Sie beim Entwerfen / Verwalten / Studieren einer Routine mehr Dinge als nur die Parameter berücksichtigen müssen.
Einige Leute denken, dass eine Routine so viele Argumente haben sollte, wie sie braucht. Ich stimme zu, aber nur für einige spezielle 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: Kurz gesagt, es kommt darauf an :
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, dass wnoise Nick sehr zustimmt und schließt seinen satirischen Beitrag mit dieser poetischen Vision (siehe Kommentare unten) der Programmierkunst ab:
quelle
Diese Antwort setzt eine OO-Sprache voraus. Wenn Sie keine verwenden, überspringen Sie diese Antwort (mit anderen Worten, dies ist keine sprachunabhängige Antwort.
Wenn Sie mehr als 3 Parameter übergeben (insbesondere intrinsische Typen / Objekte), ist es nicht so, dass es "zu viele" sind, sondern dass Sie möglicherweise die Chance verpassen, 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 dort ein neues Objekt haben sollten.
Dann überarbeiten Sie die Funktionalität Ihres neuen Objekts und würden nicht glauben, wie sehr dies sowohl Ihrem Code als auch Ihrem Verständnis der OO-Programmierung hilft.
quelle
Es scheint, als gäbe es andere Überlegungen als nur Zahlen. Hier sind einige, die mir in den Sinn kommen:
logische Beziehung zum Hauptzweck der Funktion im Vergleich zu einmaligen Einstellungen
Wenn es sich nur um Umgebungsflags handelt, kann die Bündelung sehr praktisch sein
quelle
In einem der bekannten Programmierepigramme von Alan Perlis (in ACM SIGPLAN Notices 17 (9), September 1982) heißt es: "Wenn Sie eine Prozedur mit 10 Parametern haben, haben Sie wahrscheinlich einige verpasst."
quelle
Laut Steve McConnell in Code Complete sollten Sie
quelle
Wenn die Liste in meiner IDE eine Zeile überschreitet, ist 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.
quelle
Ich stimme im Allgemeinen mit 5 überein. Wenn es jedoch eine Situation gibt, in der ich mehr brauche und es der klarste Weg ist, das Problem zu lösen, würde ich mehr verwenden.
quelle
Sieben Dinge im Kurzzeitgedächtnis?
quelle
In Worst 5 Code Snippets , überprüfen Sie die zweite : „Ist das ein Konstruktor“. Es hat wie über 37 ⋅ 4 ≈ 150 Parameter:
quelle
Eins mehr als nötig. Ich will nicht glib sein, aber es gibt einige Funktionen, die notwendigerweise einige Optionen benötigen. Beispielsweise:
Es gibt 6 Argumente, von denen jedes wesentlich ist. Darüber hinaus gibt es keine gemeinsame Verbindung zwischen ihnen, um eine Bündelung zu rechtfertigen. Vielleicht könnten Sie "struct mmapargs" definieren, aber das wäre schlimmer.
quelle
prot
undflags
hätte zusammengerollt werden können, wenn der Designer der Meinung wäre, dass 5 irgendwie eine magische Zahl ist, die viel besser als 6 ist. Ein bisschen wie die Art und Weise, wieopen
der Lese- / Schreibmodus mit allen anderen verschiedenen Flags kombiniert wird. Und vielleicht könnten Sie es loswerden,offset
indem Sie angeben, dass der zugeordnete Abschnitt an der aktuellen Suchposition von beginntfiledes
. Ich weiß nicht, ob es Situationen gibt, in denen Siemmap
eine Region erreichen können, zu der Sie nicht in der Lage sindlseek
, aber wenn nicht, ist dies nicht unbedingt erforderlich.mmap
ist ein gutes Beispiel dafür, dass einige Designer und Benutzer eine lange Liste von Parametern bevorzugen, während andere es vorziehen, einige Schritte durchzugehen, um eine kleinere Anzahl von Parametern vorzubereiten, bevor sie den Anruf tätigen.Laut Perl Best Practices ist 3 in Ordnung, 4 ist zu viel. Es ist nur eine Richtlinie, aber in unserem Shop versuchen wir, uns daran zu halten.
quelle
Ich würde die Grenze für öffentliche Funktionen selbst auf 5 Parameter ziehen.
Meiner Meinung nach sind lange Parameterlisten nur in privaten / lokalen Hilfsfunktionen zulässig, die nur an 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 verstehen sollte) sich darum kümmern müssen Aufruf dieser Funktion.
quelle
Eine verwandte Frage, die Sie berücksichtigen sollten, ist, wie kohärent 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 der Zusammenhalt 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.
quelle
97 klingt genau richtig.
Weniger und Sie verlieren an Flexibilität.
quelle
Ich halte als allgemeine Faustregel bei drei Parametern an. Mehr und es ist 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.
quelle
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. Lassen Sie einfach den Code die Regeln diktieren. Es ist offensichtlich, dass bei vielen Parametern der Hauptteil der Funktions- / Klassenmethode groß genug ist, um diese zu verwenden. Und große Codefragmente können normalerweise überarbeitet und in kleinere Teile aufgeteilt werden. Sie erhalten also eine Lösung gegen viele Parameter als kostenlosen Bonus, da diese auf die kleineren überarbeiteten Codeteile aufgeteilt werden.
quelle
Eine Sache, die ich aus Sicht der Leistung hervorheben möchte, ist, dass abhängig davon, wie Sie Parameter an eine Methode übergeben, das Übergeben vieler Parameter nach Wert das Programm verlangsamt, da jeder Parameter kopiert und dann auf den Stapel gelegt werden muss.
Die Verwendung einer einzelnen Klasse zur Erfassung aller Parameter würde besser funktionieren, da ein einzelner Parameter, der als Referenz übergeben wird, elegant und sauberer und schneller wäre!
quelle
Meiner Meinung nach könnte es Fälle geben, in denen Sie 4 oder eine feste Anzahl überschreiten. Dinge, auf die man achten sollte, könnten sein
Unter dem Gesichtspunkt der Benutzerfreundlichkeit oder des Lesens von Code denke ich, wenn Sie Ihre Methodensignatur irgendwie "umbrechen" müssen, sollten Sie innehalten und nachdenken, es sei denn, Sie fühlen sich hilflos und alle Bemühungen, die Signatur kleiner zu machen, führen dazu kein Ergebnis. Einige sehr gute Bibliotheken in Vergangenheit und Gegenwart verwenden mehr als 4-5 Kinderwagen.
quelle
Meine Faustregel lautet, dass ich mich lange genug an die Parameter erinnern muss, um einen Anruf zu betrachten und zu sagen, was er tut. Wenn ich mir also die Methode nicht ansehen und dann zu einem Aufruf einer Methode wechseln kann und mich daran erinnere, welcher Parameter was tut, 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 erstellen, die die Parameter enthalten, und diese übergeben, wenn Sie den von Ihnen festgelegten Grenzwert überschreiten. Siehe Martin Fowlers Refactoring- Buch und das Kapitel über die Vereinfachung von Methodenaufrufen.
quelle
Dies hängt stark von der Umgebung ab, in der Sie arbeiten. Nehmen Sie zum Beispiel Javascript. In Javascript können Sie Parameter am besten mit Objekten 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.
quelle
Ich bin damit einverstanden, dass 3 in Ordnung ist, 4 ist zu viel als Richtlinie. 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 viele Ausnahmen und in den meisten Fällen ist es schwierig, drei Parameter zu ermitteln.
quelle
Wenn ich 7-10 Parameter in einer Routine habe , möchte ich sie in einer neuen Klasse bündeln, aber nicht, wenn diese Klasse nichts anderes als eine Reihe von Feldern mit Gettern und Setzern wäre - die neue Klasse muss etwas anderes tun , als Werte in und zu mischen aus. Ansonsten würde ich mich lieber mit der langen Parameterliste abfinden.
quelle
Es ist eine bekannte Tatsache, dass Menschen im Durchschnitt 7 +/- 2 Dinge gleichzeitig im Kopf behalten können. Ich verwende dieses Prinzip gerne mit Parametern. Unter der Annahme, dass Programmierer alle überdurchschnittlich intelligente Menschen sind, würde ich sagen, dass alles, was 10+ ist, zu viel ist.
Übrigens, wenn Parameter in irgendeiner Weise ähnlich sind, würde ich sie eher in einen Vektor oder eine Liste als in eine Struktur oder Klasse einfügen.
quelle
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, sollten 10 oder mehr Parameter benötigt werden, wen interessiert das?
Wenn es ein paar Mal pro Frame aufgerufen wird, 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).
quelle
Laut Jeff Bezos von Amazon kann nicht mehr als mit zwei Pizzen gefüttert werden :
quelle