Ist es eine schlechte Idee, jedes Funktions- / Methodenargument in einer neuen Zeile aufzulisten und warum?

22

Ich arbeite mit jemandem zusammen, der jedes Mal, wenn er eine Funktion aufruft, die Argumente in eine neue Zeile einfügt, z

aFunction(
    byte1,
    short1,
    int1, 
    int2,
    int3,
    int4,
    int5
) ;

Ich finde das sehr ärgerlich, da der Code nicht sehr kompakt ist, also muss ich mehr nach oben und unten scannen, um die Logik überhaupt zu verstehen. Mich interessiert, ob dies tatsächlich eine schlechte Praxis ist, und wenn ja, wie kann ich sie davon überzeugen, es nicht zu tun?

Daniel Ball
quelle
25
+1, ich weiß nicht genug, um deine Frage zu beantworten, aber ich hasse das auch. Wenn Sie jedoch so viele Argumente in einer Funktion haben, dann tut Ihre Funktion wahrscheinlich zu viel.
maple_shaft
28
Genauer gesagt, warum müssen wir uns noch gegenseitig die Vorlieben dazu ansehen? Warum können unsere IDEs sie nicht automatisch in dem von uns gewünschten Stil präsentieren?
Alex Feinman
5
Mike, ich mag es, wenn Code nur wenig Platz auf dem Bildschirm einnimmt. Aber es ist ein Kompromiss. Ich setze {in eine separate Zeile, weil es einfacher ist, mit dem Abschluss übereinzustimmen} und verstehe den Umfang des Blocks richtig. Es ist den Kompromiss wert, eine Reihe von Bildschirmimmobilien zu verlieren.
Brian Schroth
2
@ Alex: Du hast vollkommen recht. Ich denke, das Richtige wäre, eine Sprache zu haben, in der der Analysebaum des Codes auf der Festplatte gespeichert und entsprechend den Benutzereinstellungen angezeigt wird.
Neil G
1
@maple_shaft Ich verachte solche Aussagen. Nicht weil es keine Wahrheit gibt, sondern weil zu viele Menschen solchen Ratschlägen folgen, ohne Raum für Nuancen zu lassen.
Stijn

Antworten:

38

Es ist nur eine Codierungsrichtlinie, die Sie mögen oder nicht mögen. Wichtig ist, dass Sie und Ihre Kollegen zustimmen, es zu verwenden oder nicht.

Die beste Möglichkeit, die Lesbarkeit zu verbessern, besteht offensichtlich darin, die Anzahl der Argumente zu begrenzen.

Martin Wickman
quelle
24
Zu viele Leute reduzieren Argumente, indem sie sie in einem Array ablegen. Ich würde eher ein hässliches Durcheinander als einen saubereren Code mit versteckter Komplexität sehen.
Satanicpuppy
18
Arrays sind nicht der richtige Weg. Möglicherweise verbirgt sich eine Struktur in den Argumenten, oder die Funktion tut zu viel und sollte aufgeteilt werden.
Michael K
4
Ich finde, dass die Verwendung mehrerer Zeilen hilft, den Code lesbar zu machen, wenn die IF-Parameter lange Ausdrücke oder einige zu viele sind. Ansonsten ist es nur nervig.
PedroC88
3
Das Einfügen in ein Datenübertragungsobjekt verschiebt nur das Problem. Wenn alle Argumente erforderlich sind, müssen sie alle obligatorische Argumente des DTO-Konstruktors sein. Das bedeutet, dass Sie immer noch so viele Argumente haben.
Scott Whitlock
21

Es ist eine Frage der Präferenz. Bei komplizierten Funktionsaufrufen, bei denen Sie jeden Parameter dokumentieren möchten oder bei denen die Variablen ziemlich lang sind und viele davon vorhanden sind, kann dies hilfreich sein.

Beispielsweise:

do_complex_op(
      0, //Starting state, always 0, ask Joe why
      X, //X-coord of thingy
      y, //Y-coord of thingy
      73, //in this case, we don't want to use Z but want constant 
      dlogMessageTitle, //message for dialogue title
      dlogMessageText, //message for dialogue contents, don't care about this.
      SomethingIP, //IP of something-or-other server, can be NULL, won't crash.
      someObject.childObject.getValue(key1).HVAL, //very long path to HVAL
      someObject.childObject.getValue(key1).LVAL, //very long path to LVAL
      this.parentWindow.owner.mainTextBox.text.value.trim, //get the trimmed text, untrimmed text causes weird output
      pvrMainSettingForLongBlahs.getObjectByPath(somePath),
      pvrMainSettingForLongBlahs.K_TCA_UPPER_LIMIT,
      pvrMainSettingForLongBlahs.K_ENDPOINT_COMPLIANCE_LEVEL,
 );

Bei Sprachen, die benannte Parameter zulassen, ist dies häufiger der Fall, wenn Sie die Parameternamen verwenden (Beispiel in PL / SQL):

PKG_SOME_TEST_CODE.FN_DO_SOMETHING( in_text => 'test text',
                                    in_id => v_id,
                                    in_ref_id => v_ref_id,
                                    out_array_for_storage => v_bArray); 

Aber ich stimme Ihnen zu, dass, wenn der Funktionsaufruf einfach ist und nicht zu viele Parameter, dies ärgerlich werden kann, wie zum Beispiel:

setColour (
    r,
    g,
    b
 );

Ich finde es viel leichter zu lesen als

 setColour(r,g,b);

Für @ammoQ:

rc=a(b,c(d,e(f)))

rc=a(
     b,
     c(
       d,
       e(
         f
        )
      )
    )
FrustratedWithFormsDesigner
quelle
11
Das erste Beispiel ist eine falsche Antwort auf ein echtes Problem. Warum nicht explizite Variablenanmeldungen verwenden?
Deadalnix
@deadalnix: Guter Punkt, etwas aufgeräumt.
FrustratedWithFormsDesigner
1
Wahr. Es ist jedoch nicht immer ein Problem mit Variablennamen. Es hat mehr mit langen Variablennamen, Argumenten mit Standardwerten usw. zu tun
inspectorG4dget
4
Ich würde argumentieren, dass die bessere Lösung des Problems darin besteht, do_complex_op () umzugestalten, sodass eine Struktur als Parameter verwendet wird. Dann können Sie es tun do_complex_op(new paramStruct { StartingState = 0, XCoord = xcoord }), dann wird es
selbstdokumentierend
1
@KallDrexx: Ich stimme zu, aber manchmal ist das Ändern des Codes keine Option, z. B. wenn es sich um eine Funktion in der Bibliothek eines anderen handelt. Sicher, ich könnte einen Wrapper erstellen, aber ich muss immer noch die ursprüngliche Funktion aufrufen .
FrustratedWithFormsDesigner
10

IMO ist alles, was ungewöhnlich ist, eine schlechte Übung, es sei denn, es ist besser als der übliche Stil. „Geschmackssache“ ist eine schlechte Entschuldigung für das Schreiben von Code, der für die meisten Programmierer schwerer zu lesen ist als nötig, da eine arme Seele, die nicht an diesen Stil gewöhnt ist, diesen Code eines Tages pflegen muss.

Zeigen Sie die Quelle von Beispielen in MSDN oder ähnlichen Sites, große Open-Source-Codebasen usw., um zu beweisen, dass dies relativ einfach ist. Zeigen Sie die Ausgabe von Code-Verschönerern. Zeigen Sie am Ende, wie es jeder in Ihrem Team macht. Akzeptiere keinen schlechten Stil, nur weil jemand zu stur ist.

user281377
quelle
Hm ... wie könnten wir mit diesem Ansatz jemals eine neue bewährte Methode einführen (oder, gramatisch richtig: eine bessere Methode )?
Treb
2
Treb: Klar, zeigen Sie einfach, dass die bessere Praxis tatsächlich besser ist , nicht nur anders .
user281377
4
Aber "schwerer zu lesen" ist an sich subjektiv und Ansichtssache. Für mich ist ein Argument pro Zeile einfacher visuell zu analysieren als zwei, drei oder vier Argumente pro Zeile. Und ich unterbreche einen Anruf immer in mehrere Zeilen, wenn er die 100-Zeichen-Marke im Editor überschreitet.
Toby
2
Meh. "Schwer zu lesen" kann objektiv gemessen werden. Es ist eher nicht so. Darüber zu streiten macht mehr Spaß.
JasonTrue
1
Sie kann objektiv gemessen werden, jedoch nicht unabhängig von der Person, die die Messung durchführt.
jk.
9

Nun, hier ist ein Downvote-Köder. Ich bin nie beschuldigt worden, das Populäre getan zu haben. Wenn Dinge in eine Zeile passen, passen sie natürlich in eine Zeile.

Aber mein Hauptanliegen ist nicht, ob der Code "hässlich" oder "hübsch" ist. Mein Hauptanliegen ist, wie einfach es ist, Änderungen zu verstehen und vorzunehmen, ohne Fehler zu machen.

Wenn die Argumente lang sind und es viele gibt, warum sie nicht in separate Zeilen setzen? Meiner Meinung nach ist es dadurch einfacher zu erkennen, was sie sind, und sie bei Bedarf zu ändern. Außerdem kann ich jedem Argument einen Kommentar hinzufügen, wenn ich möchte.

Ich möchte auch die Möglichkeit eines Fehlers minimieren, wenn ich einer Funktion ein Argument hinzufüge oder daraus entferne. Dies ist am Ende einer Argumentliste wahrscheinlicher als am Anfang. Aus diesem Grund ziehe ich es vor, das Komma (,) am Anfang einer Zeile und nicht am Ende einzufügen. Wenn ich dann zum Beispiel ein Argument am Ende der Liste entfernen oder hinzufügen möchte, handelt es sich um eine einzeilige Bearbeitung. Ich muss nicht mit dem Komma fummeln, das am Ende aller Zeilen stehen muss, sondern mit dem letzten, wo das letzte mit einer Klammer enden muss.

Also (Junge, ich werde dafür geflammt) schreibe ich es so:

nameOfFunction(firstArgument
    , secondArgument // optional comment
       ...
    , lastArgument   // optional comment
    );

Wenn es eine Funktion mit fünf bis zwanzig Argumenten gibt, ist die Funktion nicht auf einmal so gekommen. Es wuchs mit der Zeit, was bedeutete, dass es viele Änderungen gab. Jede nicht abgeschlossene Bearbeitung ist ein Syntaxfehler oder ein Fehler. Ich behaupte also nicht, dass das hübsch ist. Ich behaupte, es hilft, die Änderungen richtig zu machen.

(Und für diejenigen, die sagen, ich sollte stattdessen eine Struktur übergeben, ist alles, was das Problem verdrängt, da Sie eine Reihe von Codezeilen benötigen, um die Struktur auszufüllen, und nicht den zusätzlichen Code, um sie zu deklarieren und zuzuweisen.)

Mike Dunlavey
quelle
1
Ich persönlich halte dies für eine großartige Antwort, da Sie Ihre Argumentation sehr gut erklärt haben. Gute Arbeit, Mike.
Jordanien
8

Ich würde es auch nicht nennen. Die beste Vorgehensweise, bei der ich bisher gearbeitet habe, bestand darin, Funktionsaufrufe nur in einer Zeile zu haben, es sei denn, Sie müssten einen größeren Betrag horizontal scrollen, um den gesamten Anruf zu sehen. Es ist ein Urteilsspruch, aber ich würde definitiv sagen, dass es nicht in Einklang steht, alle Funktionen wie diese einzusetzen, es sei denn, dies ist der von Ihrer Organisation festgelegte Standard.

Aus diesem Grund empfiehlt es sich, dass eine Organisation eine Reihe von Leitfäden erstellt, an die sich alle Programmierer halten sollten. Es dreht sich alles um Konsistenz und Lesbarkeit.

Jarrod Brennnesseln
quelle
5

Es macht es einfacher:

  • Argumente neu ordnen.
  • Argumente auskommentieren oder deaktivieren.
  • Sehen Sie genau, welches Argument sich geändert hat, wenn Sie Unterschiede in Ihrem Versionskontrollsystem anzeigen
  • Vermeiden Sie das erneute Einrücken und Umbrechen von Wörtern, wenn Sie ein Argument hinzufügen oder entfernen oder den Funktionsnamen ändern. (Auch wenn Ihr Editor automatisch einrückt, erstellen Sie immer noch viele nicht hilfreiche Whitespace-Änderungen, die das Verfolgen von Änderungen in Ihrem Versionskontrollsystem erschweren.)
Graham Borland
quelle
4

Ich würde sagen, dass Funktionsaufrufe alle in einer Zeile sein sollten, es sei denn, sie überschreiten Ihre Standardcodebreite erheblich (häufig 80 Zeichen, häufig ein Grund für Argumente :-).

Ich sehe keinen Vorteil für diesen Stil. Es sieht subjektiv hässlich aus, und ich finde es ein Schmerz, wenn ich Code suche. Zum Beispiel möchten Sie vielleicht schnell suchen und sehen, ob die Funktion jemals mit einem bestimmten Parameter aufgerufen wird, der als NULL übergeben wird. Dies ist visuell einfach, wenn sich alle Parameter in einer Zeile befinden, und schwieriger, wenn sie auf diese Weise aufgeteilt werden.

Luke Graham
quelle
Diese 80-Zeichen-Sache muss gehen, es gibt einfach keine technisch gültigen Gründe mehr dafür. Wir leben jetzt in einer Ära von 19xx x 16xx Monitoren und einstellbaren Schriftarten und Schriftgrößen.
Anon
4
@anon: Gültige Gründe dafür? Warum wird Ihrer Meinung nach Text in Spalten gedruckt und Bücher sind schmaler als sie sein könnten? Weil das menschliche Auge beim Lesen über sehr lange Zeilen den Überblick verliert.
Zan Lynx
4
@anon: Ich verwende meinen Breitbild-Bildschirm auch gerne, um zwei oder drei Dateien in einer horizontalen Aufteilung zu öffnen, die auf 80-100 Zeichen in einer Zeile zurückgeht.
Zan Lynx,
4
@anon: Technisch nein, praktisch: verdammt JA. Zan Lynx hat vollkommen recht, und es gibt noch weitere Gründe: Zusammenführen, Vergleichen, Verwenden von Befehlszeilendienstprogrammen ... Oh und viel Glück beim Fokussieren auf 8p-Schrift, wenn Sie älter werden: o)
MaR
3

Ich habe diesen Stil oft auf Funktion gesehen Erklärungen oder Definitionen , aber nie auf einen Anruf (bis jetzt). Da macht es manchmal Sinn, einen Kommentar für einzelne Parameter übersichtlicher hinzuzufügen. Es scheint, als hätte er diesen Stil auf Calls kopiert, ohne die zugrunde liegenden Gründe zu kennen. Sie haben ein gutes Argument dagegen und er scheint kein gutes dafür zu haben, also haben Sie meine Stimme, aber ich bin nicht derjenige, den Sie überzeugen müssen.

Karl Bielefeldt
quelle
Ich sehe beide bei Anrufen. Wenn die Parameterliste zu lang ist, sollte sie auf mehrere Zeilen aufgeteilt werden. Wenn die Parameter normalerweise nicht innerhalb von Breitengrenzen gruppiert werden, werden sie voraussichtlich in separaten Zeilen angezeigt. Wenn die Funktions- und Parameternamen gut in eine Zeile passen, sehe ich sie oft so angeordnet.
BillThor
2

Verstößt es gegen die Kodierungsstandards des Unternehmens?

Wenn nicht, dann leiten Sie eine Diskussion über die Standards ein und darüber, welche Änderungen die Leute gerne sehen würden. Stellen Sie sicher, dass Sie dies als eines der Dinge ansprechen, die Sie ändern möchten.

Besprechen Sie ausführlich, warum Sie Sie dies nicht für nützlich halten, und gewinnen Sie hoffentlich den Tag. Sie werden nie erfahren, dass Ihr Kollege Sie davon überzeugen könnte, dass sein Weg der beste ist;)

Sobald Sie einen aktualisierten Standard erhalten haben, ist dokumentiert, worauf jeder Codieren sollte. Wenn Ihr Kollege dies weiterhin tut, können Sie ihn in seinen Codereviews ansprechen.

ChrisF
quelle
2

Es mag für Sie funky aussehen, aber es erleichtert die Arbeit an Code. Während des Refactorings können Sie sehr einfach einzelne Argumente auskommentieren und Ihren Refactor überprüfen, bevor Sie Dinge tatsächlich löschen. Sie können Typen auch ganz einfach auskommentieren und temporär ersetzen.

Es ist auch einfacher zu lesen als:

int f(int, int, int,
      char, double, int
      X const&, Y)
{}

Ich bin nicht so extrem geworden, wie Sie es gezeigt haben (da es keine Namen für die Parameter gibt, ist es nicht sehr nützlich), aber ich habe mir angewöhnt, jeden Parameter in einer eigenen Zeile aufzuteilen oder überhaupt nicht aufzuteilen.

Der wichtige Teil ist, dass Ihr Code auf Standard-80-Farben-Displays gedruckt oder angezeigt werden kann und dennoch lesbar ist.

Edward Strange
quelle
2

Sie werden selten eine ehrliche Antwort von einem Programmierer für so etwas bekommen. Jeder antwortet nur mit dem, was er will oder nicht. Die Wahrheit ist, dass die einzige "schlechte Praxis", mit der wir alle manchmal zu kämpfen haben, Ihre eigene Inflexibilität ist.

Sie müssen brutal ehrlich zu sich selbst sein, um zwischen Dingen, die eigentlich schlecht sind, und Dingen, die Sie nur nerven, unterscheiden zu können. Die Wahrheit ist, dass Sie in C / C ++ und ähnlichen Sprachen selten eine Einrückungsmethode finden, die sich spürbar auf die Verständlichkeit des Codes auswirkt. Die meisten Diskussionen über diese Art von Dingen haben nur beide Seiten mit Leuten gestapelt, die lächerliche, unaufrichtige Argumente vorbringen, um zu versuchen, ihre eigene persönliche Präferenz zu rechtfertigen.

Was meiner Lektüre nach genau das ist, was Sie in dieser Frage fordern: ein lächerliches, unaufrichtiges Argument, um Ihre persönliche Präferenz zu rechtfertigen.

Dan Olson
quelle
0

Um ehrlich zu sein, hängt es von der Person ab. Ich würde für komplexe Funktionen sagen, wie durch das erste Beispiel von FrustratedWithForms demonstriert, dann ja; ansonsten ein großes NEIN. Andererseits bevorzuge ich es deshalb, die IDE-Funktionalität von Code willkürlich anzuwenden.

Dunkler Stern1
quelle
0

"Ich bin gespannt, ob das wirklich eine schlechte Praxis ist ..."

Ja, es ist eine schlechte Praxis, es sei denn, die Liste der Variablen ist ungewöhnlich lang. In diesem Fall liegt das Problem wahrscheinlich am Design der Funktion. Warum nicht ein Objekt übergeben, das viele der Parameter kapselt?

"... und wenn ja, wie kann ich sie davon überzeugen, es nicht zu tun?"

Binde sie fest und kitzle sie weiter, bis sie damit einverstanden sind, diesen Mist zu stoppen.

ybakos
quelle
"Warum nicht ein Objekt übergeben, das viele der Parameter kapselt?" OK, jetzt haben Sie das Problem auf das neue Objekt verschoben. Es benötigt immer noch die gleiche Anzahl von Parametern (z. B. über seinen Konstruktor), sodass Sie immer noch das gleiche Problem haben.
Stijn
-2

Warum verschwendest du Zyklen für so ein unbedeutendes Anliegen? Starten Sie einfach Ihre vertrauenswürdige IDE, öffnen Sie die Datei und formatieren Sie sie neu. Voila! Es wird in welcher Form auch immer Sie wollen.

Kommen wir nun zu dem wirklich wichtigen Thema - vi oder emacs, LOL.

SnoopDougieDoug
quelle
Und wenn Sie dann kommen, um das in die Quellcodeverwaltung zu überprüfen?
pdr
-2

Ich würde sagen, wenn die Argumente in eine Zeile passen, tun Sie dies. Wenn nicht, sorgt ein Argument pro Zeile für eine gute Lesbarkeit.

foo(arg1, arg2, arg3, arg4, arg5)

gegen

foo(
    arg1=arg1,
    arg2=arg2,
    arg3=arg3,
    arg4=arg4,
    arg5=arg5,
    arg6=arg6,
    arg7=arg7
)
user271413
quelle
3
dies scheint nicht zu bieten alles wesentliche über gemacht Punkte und erläuterte vor 14 Antworten
gnat