読みやすくするための名前付き引数(パラメーター)


11

かなり前にADAで多くのプログラムを作成しましたが、関数を呼び出すときに引数に名前を付けるのは正常でした-SomeObject.DoSomething(SomeParameterName => someValue);

C#が名前付き引数をサポートするようになったので、引数の意味が明らかでない場合にこの習慣に戻すことを考えています。

引数の意味が常に明らかであると主張するかもしれませんが、ブール引数を持ち、呼び出し元が「true」または「false」を渡す場合、名前で値を修飾すると、呼び出しサイトが読みやすくなります。

contentFetcher.DownloadNote(note、manual:true);

trueまたはfalse(この場合は手動、自動)を使用する代わりにEnumを作成できると思います。

コードを読みやすくするために、時々名前付き引数を使用することについてどう思いますか?


メソッドの上部にあるパラメーターコメントも役立ちます。
アミールRezaei

1
@ amir-rezaei:メソッドの上にあるパラメーターコメントは、コメントを信頼できる場合にのみ役立ちます。優れた開発者優れたコードレビュープロセスがない限り、私はコメントを信用しません。
-btilly

Adaの1回限りのユーザーとして、私はあなたが説明するように時折使用しています。それは私がそれらをAda、BTWで使用されていることを覚えている方法です-私はそれを「異常」とは呼びませんが、「通常」という言葉はほとんどの呼び出しがパラメータ名を指定することを意味するようです、それは私が物事を覚えている方法ではありません。もちろん慣習は異なりますが、どの言語のIMOでも不必要な混乱は悪い慣習です。
Steve314

Adaでのあなたの使用に同意します-それは私たちがいつもやったことではありませんでしたが、それが助けた場所です。
ダミアン

回答:


7

これはC ++の開発で提案されたものであり、Stroustrupが153ページ以降の「C ++の設計と進化」で説明しています。提案は整形式で、Adaでの以前の経験に基づいています。採用されませんでした。

最大の理由は、多数のパラメーターを持つ関数を推奨したくないということです。言語の追加機能にはそれぞれ費用がかかり、悪いプログラムを書きやすくする機能を追加する必要はありませんでした。

また、特に通常のヘッダーとコードファイルの規則において、標準的なパラメーター名が何であるかという問題も提起されました。一部の組織では、.hファイルに長くてわかりやすいパラメーター名があり、.cppファイルに入力するのが短くて簡単です(必要に応じてファイルのサフィックスを置き換えます)。これらが同じであることを要求すると、コンパイルに追加コストがかかり、ソースファイル間で名前が混同されると、微妙なバグが発生する可能性があります。

関数呼び出しではなくオブジェクトを使用して処理することもできます。多数のパラメーターを指定したGetWindow呼び出しの代わりに、多数のプライベート変数を使用してWindowクラスを作成し、必要に応じてセッターを追加します。セッターを連鎖させることで、のようなものを書くことができmy_window.SetColor(green).SetBorder(true).SetBorderSize(3);ます。また、実際に作業を行う関数を呼び出す、異なるデフォルトを持つ異なる関数を持つこともできます。

のドキュメント化の効果が心配なだけであればcontentFetcher.DownloadNote(note, manual : true);、いつでものようなものを書くことができるcontentFetcher.DownloadNote(note, /* manual */ true);ので、ドキュメント化ではあまり役に立ちません。


おもしろいことに、AdaからCに移行したとき、私はあなたが記述した規約を使い始めました-コードレビュアーはそれを嫌っていました。多数のパラメーターに使用しないことに同意します。
ダミアン

7

これは、「ベストプラクティス」ではなく、不良コードを読みやすくすることの問題だと思います。

20個のパラメーターを使用するメソッド(または請負業者)を持つことは「悪臭」であり、設計の問題が原因である可能性があります。ただし、メソッドが多くのパラメーターをとるときにコードで作業することを余儀なくされた場合、名前付きパラメーターはコードの理解を難しくします。

メソッドに1つまたは2つのパラメーターしかなく、メソッド名からパラメーターが明確な場合、名前付きパラメーターは何も追加しません。 これは理想的なケースです。

作業するすべてのコードが「クリーンコード」ブックと同じように書かれている場合、名前付きパラメーターの使用はほとんどありませんが、現実の世界に住んでいます。


1
2つのパラメーターが同じタイプで、どちらがどちらであるかがわからない場合、2つのパラメーターを持つ関数は混乱を招く可能性があります。もちろん、その手がかりを提供する方法で関数に名前を付けることはできますが、実際にはパラメータ名が何をするのかを実際にやっています-ただし、コンテキスト(たとえば、パラメータ)どのパラメータがどのパラメータであるかを明確にします。
Steve314

1
@ Steve314例:void TrackDataChange(Data oldData, Data newData)
アレクサンダー

3

パラメーター名を追加すると読みやすくなることに同意します。しかし、私が読んだ本のほとんどは、ブール値の切り替えは悪い習慣だと考えているようです。私は時々これをします:

public Content DownloadNote(Note note)
{
    return downloadNote(note, manual: false);
}

public Content DownloadNoteManually(Note note)
{
    return downloadNote(note, manual: true);
}

これにより、APIを実装する際の柔軟性が向上します。また、複数のブールスイッチがある場合でも、それらのすべてを同時にアクティブにできるわけではない場合を制御できます。


3
x個の選択肢がある場合、2 ^ x個のフロントエンドを作成しますか?
apoorv020

@ apoorv020-メソッド呼び出しに十分なパラメーターがあり、2 ^ xが重要になった場合、パラメーター値を保持する新しいクラスを作成し、1つのパラメーターを渡すだけです。
スコットホイットロック

@ scott-whitlock:オプション1-オブジェクトを作成し、xプロパティを設定し、オブジェクトでメソッドを1回呼び出します。オプション2-名前付きパラメーターxを使用してメソッドを呼び出します。どちらが良いかはあなたの言語に依存します。動的に型付けされた言語では、オプション1はゲインなしで大幅に多くの定型文を必要とするため、さらに悪化します。静的に型付けされた言語では定型文を追加しますが、間違った名前のキーのテストは実行時ではなくコンパイル時に行われます。したがって、オプション1はC#の方が優れていますが、オプション2はPythonの明確な勝ちです。
-btilly

@btilly-Ianが指摘したように、Clean Codeは、2つまたは3つ以上のパラメーターを持つ関数を使用しないことを明確に示してます。公平を期すために、静的に型指定されたJavaを扱っていました。OPは、静的に型指定されたC#についても質問しています。パラメータの長いリストよりも、関数のオーバーロードや正確に異なる名前の関数名を使用することを引き続き希望します。
スコットホイットロック

@ scott-whitlock:私たちは実際に同意しませんか?私たちは、C#で何が最善であるかに同意します。どちらもClean Codeの言うことを知っています。私のポイントは、なぜそれが良いのかを理解することが重要であり、アドバイスが異なる環境に適合するかどうかを知ることです。
btilly

3

私は、メソッドの名前から型とセマンティクスが明確でない状況での名前付きパラメーターを強く信じています。私の経験では、ドキュメントを読む人はほとんどいません。

そうは言っても、名前付きパラメーターは、意味のある引数リストを作成し、ヘルパーオブジェクトを使用して(意味的に関連する引数を「結び付ける」)、関連する列挙を使用する代わりにすべきではありません。


0

これは、いくつかのわずかに異なる方法で何かをしなければならない1つの関数があり、何をすべきかを決定する方法がパラメーター値に基づいている、非OO言語でより便利だと思います。OOPの世界では、関数をオーバーロードしますが、それが不可能な場合は、一連のフラグ(または一連の値、渡されるかどうかがフラグ)を渡すことになります。

ある程度は読みやすいと思います。しかし、他の人が述べたように、多くのパラメーターを持つことはコードのにおいであるため、C#のようなオブジェクト指向言語でこれを使用することはあまりありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.