すべての関数/メソッド引数を新しい行にリストするのは悪い考えですか?なぜですか?


22

私は、関数を呼び出すたびに引数を新しい行に置く人と仕事をしています。

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

コードが非常にコンパクトではないことを意味するため、これは非常に迷惑です。したがって、実際にロジックを理解するには、さらに上下にスキャンする必要があります。これが実際に悪い慣行であるかどうかを知りたいのですが、もしそうなら、どうすれば彼らにそれをしないように説得できますか?


25
+1、あなたの質問に答えるのに十分な知識がありませんが、これも嫌いです。ただし、関数内にこれほど多くの引数がある場合、関数はおそらく多すぎます。
maple_shaft

28
さらに重要なのは、なぜこれについてお互いの好みを見なければならないのですか?なぜ私たちのIDEは私たちが望むスタイルで自動的にそれを提示できないのですか?
アレックスファインマン

5
マイク、私はコードが最小限の画面領域を占有するのが好きです。しかし、それは妥協です。{を別の行に配置すると、終了}との一致が容易になり、ブロックのスコープを正しく理解できるようになります。スクリーンの不動産を失うというトレードオフに値します。
ブライアンシュロス

2
@アレックス:あなたはまったく正しい。正しいことは、コードの解析ツリーがディスクに保存され、ユーザーの好みに応じて表示される言語にすることだと思います。
ニールG

1
@maple_shaftそのようなステートメントは軽deします。真実がまったくないからではなく、あまりにも多くの人々がニュアンスの余地を残さずにそのようなアドバイスに従っているからです。
-Stijn

回答:


38

それはあなたが好むかもしれないし好まないかもしれない単なるコーディングガイドラインです。重要なことは、あなたとあなたの同僚がそれを使用するかどうかに同意することです。

明らかに、読みやすさを向上させる最良の方法は、引数の数を制限することです。


24
配列にダンプすることで引数を減らす人が多すぎます。私はむしろ、隠れた複雑さを備えた、見た目がきれいなコードよりもthanい混乱を見たいと思います。
悪魔のような子犬

18
配列は進むべき道ではありません。argsに隠れている構造があるかもしれませんし、関数が多すぎて分割されているかもしれません。
マイケルK

4
複数行を使用すると、コードが判読可能なIFパラメーターが長い表現または数が多すぎるようになります。それ以外の場合は、単に迷惑です。
PedroC88

3
それらをデータ転送オブジェクトに入れると、問題が移動します。すべての引数が必要な場合、それらはすべてDTOのコンストラクターの必須引数である必要があります。これは、その数の引数がまだあることを意味します。
スコットホイットロック

21

それは好みの問題です。各パラメーターを文書化する複雑な関数呼び出しの場合、または変数がかなり長く、それらの多くが存在する場合、これは適切です。

例えば:

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,
 );

名前付きパラメーターを許可する言語では、パラメーター名を使用する場合にこれがより一般的です(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); 

しかし、関数呼び出しが単純でパラメーターが多すぎない場合、次のような迷惑になる可能性があることに同意します。

setColour (
    r,
    g,
    b
 );

読みやすいと思う

 setColour(r,g,b);

@ammoQの場合:

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

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

11
最初の例は、実際の問題に対する間違った答えです。最初に明示的な変数のテーマを使用しないのはなぜですか?
deadalnix

@deadalnix:良い点です。少し整理しました。
FrustratedWithFormsDesigner

1
本当です。ただし、変数名の問題とは限りません。それは長い変数名、デフォルト値の引数、などと関係してより多くのです
inspectorG4dget

4
この問題に対するより良い解決策は、do_complex_op()をリファクタリングして、構造体をパラメーターとして取得することです。その後、あなたはそれを行うことができdo_complex_op(new paramStruct { StartingState = 0, XCoord = xcoord })、それからそれは自己文書化され、読みやすくなります
-KallDrexx

1
@KallDrexx:同意しますが、他の誰かのライブラリの関数の場合など、コードを変更することはオプションではありません。確かに、ラッパーを作成することはできますが、いつか元の関数を呼び出す必要があります。
FrustratedWithFormsDesigner

10

IMOは、通常のスタイルに対する優位性が明確に証明されない限り、一般的ではないものすべて悪い習慣です。「好みの問題」は、大部分のプログラマーにとって必要以上に読みにくいコードを書くための言い訳です。いつか、そのスタイルに慣れていない貧しい魂がそのコードを維持しなければならないからです。

まれであることの証明は比較的簡単で、MSDNや同様のサイトでサンプルのソースを表示し、大規模なオープンソースコードベースを表示します。コードビューティファイアーの出力を表示します。最終的にはチームの他の誰もがそれをどのように行っているかを示してください。誰かが頑固すぎるからといって、悪いスタイルを受け入れないでください。


うーん...そのアプローチで、どのようにして新しいベストプラクティス(または、文法的に正しい:より良いプラクティス)を導入できるでしょうか?
トレブ

2
Treb:確かに、良いプラクティスが実際に優れているだけでなく、異なることを示すだけです。
-user281377

4
しかし、「読みにくい」というのは、それ自体主観的であり、意見の問題です。私にとって、1行に1つの引数は、1行に2、3、または4つの引数よりも視覚的に解析しやすいです。また、エディターで約100文字のマークを超える場合は、常に呼び出しを複数行に分割します。
トビー

2
えー 「読みにくい」客観的に測定できます。そうではない傾向があります。それについて議論するのはもっと楽しいです。
ジェイソンTrue

1
客観的に測定することはできますが、読書をしている人から独立して測定することはできません。
jk。

9

さて、ここでいくつかのdownvote-baitです。私は人気のあることをしたと非難されたことはありません。明らかに、物事が1行に収まる場合は、1行に収まります。

しかし、私の主な懸念は、コードが「ugい」か「きれい」かではありません。私の主な関心事は、間違いを犯さずに理解し、変更を加えることがいかに簡単かということです。

引数が長く、多くの引数がある場合、それらを別々の行に入れてみませんか?私の頭の中では、それらが何であるかを見やすくし、必要に応じてそれらを変更しやすくします。また、必要に応じて各引数にコメントを追加する余地があります。

また、関数の引数を追加または削除した場合に、最初よりも引数リストの最後で発生する可能性が高い場合、ミスをする可能性を最小限に抑えたいと考えています。そのため、コンマ(、)を行末ではなく行頭に配置することを好みます。次に、たとえば、リストの最後にある引数を削除または追加する場合は、1行の編集です。私は、最後を除くすべての行の終わりに行く必要があるコンマをいじる必要はありません。最後の行は括弧で終わる必要があります。

だから(少年、私はこれに火をつけるつもりです)私はこのように書きます:

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

5〜20個の引数を持つ関数がある場合、その関数は一度にすべてを取得しませんでした。時間の経過とともに成長し、多くの編集があったことを意味します。完了していない編集は、構文エラーまたはバグです。だから私はこれがきれいだと主張しません。私はそれが編集を正しくするのに役立つと主張しています。

(代わりに構造体を渡す必要があると言う人にとっては、構造体を埋めるために大量のコード行が必要なため、それを宣言して割り当てる余分なコードは言うまでもなく、問題を置き換えるだけです。)


1
個人的には、あなたはあなたの推論を非常によく説明してくれたので、これは素晴らしい答えだと思います。マイク、よくやった。
ジョーダン

8

私もそれを呼び出しません。私が取り組んだベストプラクティスは、通常、呼び出し全体を見るためにかなりの量を水平にスクロールする必要がない限り、関数呼び出しをすべて1行にすることでした。それは判断を呼びますが、このようなすべての機能を配置することは、それが組織によって確立された標準でない限り、間違いです。

これが、すべてのプログラマーが順守すべき一連のガイドを確立することが組織にとって良い習慣である理由です。その一貫性と読みやすさについてのすべて。


5

次のことが容易になります。

  • 引数を並べ替えます。
  • 引数をコメントアウトするか無効にします。
  • バージョン管理システムで差分を表示すると、どの引数が変更されたかを正確に確認できます
  • 引数を追加または削除するとき、または関数名を変更するときに、すべてを再インデントおよびワードラップすることは避けてください。(エディターが自動的にインデントしたとしても、バージョン管理システムでの変更を追跡するのを難しくする多くの役に立たない空白の変更を作成しています。)

4

関数の呼び出しは、標準のコード幅(多くの場合80文字、多くの場合引数の原因:-)を大幅に超えない限り、すべて1行で行う必要があります。

このスタイルには利点がありません。主観的にいように見えますが、コードを検索するときに苦痛を感じます。たとえば、特定のパラメーターをNULLとして渡して関数が呼び出されるかどうかをすばやく検索して確認することができます。これは、すべてのパラメーターが1行にある場合は視覚的に簡単ですが、このように分割されている場合は難しくなります。


この80字の文字は必ずやる必要がありますが、技術的に正当な理由はもうありません。現在、19xx X 16xxモニター、調整可能なフォント、およびフォントサイズの時代に生きています。
アノン

4
@anon:有効な理由は?なぜテキストは列に印刷され、本は本来よりも狭いと思いますか?非常に長い行を読んでいると、人間の目が見失ってしまうからです。
ザンリンクス

4
@anon:また、ワイドスクリーンを使用して、2〜3個のファイルを水平分割で開き、1行で80〜100文字に戻します。
ザンリンクス

4
@anon:技術的にいいえ、実際には:地獄はい。斬Lynxは完全に右である、加えて、追加的な理由があります:あなたが年を取るだろうと、マージ差分、コマンドラインユーティリティを使用して...ああと幸運8Pフォントに焦点を当てます。o)
MAR

3

私は頻繁に関数の宣言定義でそのスタイルを見てきましたが、呼び出しでは決して見ませんでした(今まで)。個々のパラメーターにコメントをより明確に追加できるため、時々意味があります。彼は背後にある根本的な理由を本当に知らずに、そのスタイルを電話にコピーしたようです。あなたは反対意見があり、彼は良い意見を持っていないようです。あなたは私の票を持っていますが、私はあなたが納得しなければならない人ではありません。


私は電話で両方を見ます。パラメータリストが長すぎる場合は、複数の行に分割する必要があります。パラメーターが通常、幅の制限内でグループ化されない場合は、別々の行にあると予想されます。関数名とパラメーター名が1行に収まる場合、そのように配置されていることがよくあります。
BillThor

2

会社のコーディング標準に違反していますか?

そうでない場合は、標準と、人々が何を見たいと思うかについて議論を開始します。これを、変更したいものの1つとして取り上げてください。

なぜこれが便利だと思わないのについて十分な議論をしてください。あなたの同僚が結局彼の方法が最善であるとあなたを納得させるかもしれないことを決して知らない;)

更新された標準があれば、誰もがコーディングすべきものが文書化されているので、同僚がこれを続けている場合は、コードレビューでそれを上げることができます。


2

あなたにはファンキーに見えるかもしれませんが、コードの作業が簡単になります。リファクタリング中、個々の引数を非常に簡単にコメントアウトして、実際に削除する前にリファクタリングを確認できます。型をコメントアウトして一時的に非常に簡単に置き換えることもできます。

また、以下よりも読みやすくなっています。

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

私はあなたが示しているほど極端には行きませんでした(パラメータに名前がないのであまり使用されていません)が、各パラメータを独自の行に分割するか、まったく分割しないという習慣になりました。

重要な部分は、コードを標準の80colディスプレイで印刷または表示でき、さらに読みやすいことです。


2

このようなことに対してプログラマから正直な答えを得ることはめったにありません。誰もが自分のすること、または好まないことで答えるだけです。真実は、私たち全員が時々それと格闘しているので、ここでの唯一の「悪い習慣」はあなた自身の柔軟性がないことです。

あなたは実際に悪いことと単にあなたを悩ませるものとを区別できるように、自分自身に残酷に正直でなければなりません。真実は、C / C ++および同様の言語では、コードの理解可能性に明確な影響を与えるインデントの慣行を見つけることはめったにないということです。この種のことについてのほとんどの議論では、自分の個人的な好みを正当化しようとするばかげた、不誠実な議論をしている人々が両側に積み重ねられています。

私の読書では...あなたはこの質問でまさにあなたが要求しているものです:あなたの個人的な好みを正当化するばかげた、不誠実な議論。


0

正直に言うと、それは人次第です。最初の例のFrustratedWithFormsで示されているような複雑な機能の場合は、そうです。そうでなければ大きなNO。繰り返しになりますが、これが、コードのIDE機能を任意に適用することを好む理由です。


0

「これが実際に悪い習慣かどうかを知りたい...」

はい、変数のリストが異常に長い場合を除いて、それは悪い習慣です。しかし、その場合、問題はおそらく関数の設計によるものです。多くのパラメーターをカプセル化したオブジェクトを渡してみませんか?

「...もしそうなら、どうすれば彼らにそれをしないように説得できますか?」

それらを縛り、彼らがそのがらくたを止めることに同意するまで、それらをくすぐり続けます。


「多くのパラメータをカプセル化したオブジェクトを渡してみませんか?」OK、問題をその新しいオブジェクトに移動しました。まだ同じ量のパラメーターが必要なので(たとえば、コンストラクターを介して)、同じ問題が発生します。
-Stijn

-2

なぜそんなに些細な懸念でサイクルを無駄にしているのですか?信頼できるIDEを起動し、ファイルを開いて再フォーマットするだけです。出来上がり!あなたが望む形になります。

次に、非常に重要な問題、viまたはemacs、LOLに進みましょう。


そして、それをソース管理にチェックインするようになったら?
PDR

-2

引数が1行に収まる場合、そうします。そうでない場合は、1行に1つの引数を指定すると読みやすくなります。

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

foo(
    arg1=arg1,
    arg2=arg2,
    arg3=arg3,
    arg4=arg4,
    arg5=arg5,
    arg6=arg6,
    arg7=arg7
)

3
これは、以前の14の回答で作成され説明されたポイントに対して実質的な何かを提供するようには見えません
-gnat
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.