時々(まれに)、適切な量のパラメーターをとる関数を作成することが最適なルートであると思われます。しかし、そうすると、パラメーターの順序をランダムに選択することが多いように感じます。私は通常、最も重要なパラメーターを最初に使用して、「重要度の順に」進みます。
これを行うためのより良い方法はありますか?明確性を高めるパラメーターを並べる「ベストプラクティス」の方法はありますか?
時々(まれに)、適切な量のパラメーターをとる関数を作成することが最適なルートであると思われます。しかし、そうすると、パラメーターの順序をランダムに選択することが多いように感じます。私は通常、最も重要なパラメーターを最初に使用して、「重要度の順に」進みます。
これを行うためのより良い方法はありますか?明確性を高めるパラメーターを並べる「ベストプラクティス」の方法はありますか?
回答:
一般的に:それを使用します。
関数のテスト、実際のテストを作成します。
何かあなたが実際にその機能をどうしたいと思います。
そして、それらを下に置いた順番を確認してください。
同様のことをする機能を既に持っている(または知っている)場合を除きます。
その場合:少なくとも最初の引数については、彼らがすでにやっていることに準拠します。
例えば、それらはすべて最初の引数としてドキュメント/オブジェクト/ファイルポインター/値のシリーズ/座標を取りますか?神のためにそれらの議論に準拠してください。
あなたの同僚とあなたの将来の自己を混同しないでください。
いつも同じ優先順位であるとは限りませんが、私は通常これらの規則に従います。今では自動思考プロセスだと思いますが、パブリックAPI設計を除き、考え直しはしません。
特にOOPでは、アクションまたはメッセージの意味的な意味に基づいてパラメーターを選択します。適切な名前のパラメータを持つ適切な名前のメソッドのシグネチャは次のようにする必要があります。
(これらの理由により、プリミティブの代わりにカスタム型またはエイリアスを使用すると、署名の表現力が向上する場合があります。)
最も「重要な」パラメーターが最初に来る(または次...)
頻度も重要です。特に、名前付きパラメーターはないが、位置パラメーターにデフォルト値を設定できる言語では重要です。つまり、パラメーターの順序は変わらず、N番目のパラメーターの既定値を強制する場合は、N + 1パラメーターを設定できないことは明らかです(言語にプレースホルダーパラメーターの概念がある場合を除く) )。
良いニュースは、通常、頻度は重要性に関連しているため、前のポイントと連動していることです。そして、適切なセマンティクスを持つようにAPIを作成するのはおそらくあなた次第です。
メソッド/関数が入力を受け取って出力を生成し、後者が「return」ステートメントを介して「return」または「exception system」を使用して「スロー」されない場合、渡すオプションが残っています他のパラメーター(または入力パラメーター)を使用して、呼び出し元に値を返します。これはセマンティクスに関連しており、ほとんどの場合、最初のパラメーターで出力を定義し、最後のパラメーターで出力を受け取るのが理にかなっています。
さらに、パラメーターを減らしてセマンティクスを最大化する別のアプローチは、機能的なアプローチを使用するか、Builderパターンを定義することです。したがって、入力を明確に積み重ね、出力を定義し、必要なときにそれらを取得できます。
(グローバル変数については言及していません。なぜ使用するのですか?)
使いやすさ
あなたはZJRの続く場合は、上記のほとんどは自然に表示されますアドバイス:使用それを!
リファクタリングを検討する
パラメーターの順序について心配する場合、おそらくこの心配は、上記と、APIの設計が不適切であることに原因があることがわかります。パラメーターが多すぎる場合は、おそらくコンポーネント化/モジュール化およびリファクタリングが可能です。
パフォーマンスを考慮する
一部の言語の実装は、パラメーターを使用するときにランタイムメモリ管理に非常に重要な影響を与えることに注意してください。したがって、多くの言語のスタイルブックがパラメーターリストをシンプルかつ短く保つことを推奨する理由。たとえば、最大4つのパラメーター。理由を理解するための演習として残しておきます。
Clean Codeの推奨事項に関するBevanの回答と言及は、間違いなく関連性があります!
パラメーターの順序付けを気にすることは、間違ったことを心配することであると、私は敬意をもって提出します。
ボブおじさんの本「Clean Code」では、説得力のあることに、メソッドには2つ以上の引数を含めることはできません。この場合、順序は明白または重要ではありません。
不完全ではありますが、私はボブおじさんのアドバイスに従おうとしています-そしてそれは私のコードを改善しています。
メソッドがより多くの情報を必要とするようなまれなケースでは、パラメーターオブジェクトを導入することをお勧めします。通常、これは私のアルゴリズムの鍵となる新しい概念(オブジェクト)を発見するための最初のステップであると思います。
INパラメーターを最初に、OUTパラメーターを2番目に配置しようとしました。いくつかの自然な順序でもありますが、例えばcreatePoint(double x, double y)
に強くpreferrableですcreatePoint(double y, double x)
。
addAllTo(target, something1, something2)
。
この特定のトピックに関する文書化された「ベストプラクティス」を見たことはありませんが、私の個人的な基準は、使用されているメソッドに表示される順序で、またはメソッドがデータレイヤーへのパススルーdbスキーマまたはデータレイヤーメソッドに表示される順序でリストします。
また、メソッドのオーバーロードが複数ある場合、一般的な方法は、すべての(またはほとんどの)メソッドに共通のパラメーターからリストすることで、各メソッドオーバーロードのように各メソッドが最後に追加されることに注意してください:
void func1(string param) { }
void func2(string param, int param2) { }
void func3(string param, string param3) { }
void func3(string param, int param2, string param3) { }
多くの場合、const
最初にパラメーター(つまり、値で渡すパラメーター)を配置し、次に参照で渡すパラメーターを配置するC / C ++の規則に従います。これは必ずしも関数を呼び出す正しい方法ではないかもしれませんが、各コンパイラがパラメーターを処理する方法に関心がある場合は、パラメーターを管理する規則および/またはスタックにプッシュされる順序について次のリンクを参照してください。
http://msdn.microsoft.com/en-us/library/zthk2dkh%28v=vs.80%29.aspx
私は通常、「cyprticに見えないもの」のパラメーターの順序を使用します。メソッド/関数の定義に行く必要がある回数が少ないほど良いです。そして、小さなツールチップがポップアップ(VS)されると、それがさらに簡単になります。
パラメータの行と行がある場合は、異なる設計を検討することをお勧めします。一歩下がって、それをより多くの関数/メソッドに分割する方法を確認してください。ただのアイデアですが、関数に12個のパラメーターがある場合、ほとんどの場合パラメーターの問題ではなく、設計の問題です。
時々(まれに)、適切な量のパラメーターをとる関数を作成することが最適なルートであると思われます。
多くの場合、いくつかのパラメーターを使用することは、この方法でSRPに違反するという明確な指標です。多くのパラメーターを必要とするメソッドは、1つのことだけを行うことはほとんどありません。除外は、数学関数または構成方法である場合があり、実際にはいくつかのパラメーターが必要です。悪魔が聖水を避けるので、私は複数のパラメーターを避けます。メソッド内で使用するパラメーターが多いほど、メソッドが(あまりにも)複雑になる可能性が高くなります。複雑さが増すということは、保守が難しくなり、あまり望ましくないことを意味します。
しかし、そうすると、パラメーターの順序をランダムに選択することが多いように感じます。私は通常、最も重要なパラメーターを最初に使用して、「重要度の順に」進みます。
原則として、ランダムに選択しています。もちろん、パラメータAはパラメータBよりも関連性が高いと考えるかもしれません。ただし、Bが最も適切なパラメーターであると考えるAPIのユーザーには当てはまらない可能性があります。そのため、順序を注意深く選んだとしても、他の人にとってはランダムに見えるかもしれません。
これを行うためのより良い方法はありますか?明確性を高めるパラメーターを並べる「ベストプラクティス」の方法はありますか?
いくつかの方法があります。
a)些細なケース:複数のパラメーターを使用しないでください。
b)指定していないので、どの言語を選択したか、名前付きパラメーターを持つ言語を選択した可能性があります。これは、パラメーターの順序付けの重要性を緩和することができる素晴らしい構文糖です:fn(name:"John Doe", age:36)
すべての言語でこのような機能が使用できるわけではありません。それでは何ですか?
c)ディクショナリ/ハッシュマップ/連想配列をパラメータとして使用できます。たとえば、Javascriptでは次のことが可能です:fn({"name":"John Doe", age:36})
(b)からそれほど遠くありません。
d)もちろん、Javaのような静的に型付けされた言語を使用する場合。Hashmapを使用することもできますがHashMap<String, Object>
、パラメーターの型が異なる(およびキャストする必要がある)場合は、型情報が失われます(たとえば、使用時)。
次の論理的なステップはObject
、適切なプロパティまたは構造体のようなより軽量なもの(Javaを使用している場合)を渡すことです(たとえば、C#またはC / C ++を記述する場合)。
経験則:
1)ベストケース-メソッドにパラメーターは必要ありません
2)良いケース-メソッドには1つのパラメーターが必要です
3)許容可能なケース-メソッドには2つのパラメーターが必要
4)その他のすべてのケースはリファクタリングする必要があります
多くの場合、パラメーターとしての複雑なオブジェクトの方が優れています。ほとんどのプラットフォームで機能する、名前の付いたパラメーターの貧乏人向けのバージョンです。そして、起動する動作を備えたパラメータへの扉を開きます。
してはいけないことのほとんどの例については、PHPの標準ライブラリのドキュメントを読んでみてください。
私は通常ORDER BY required DESC, SOME_MAGIC_FEELING(importancy,frequency)
、特定の慣行ではなく、「感情」(と見ることができる)に従って重要性と使用頻度を組み合わせた尺度ではなく、最初に必要な順序で注文します。
しかし、他の人が指摘したように、これを問題にする根本的な問題は、あまりにも多くのパラメーターを使用することであると思います(IMHO、3を超えるものは多すぎます)。あります興味深い記事レベッカ・マーフィさんのブログでそのことについては。
引数が1〜3個しかない場合、正しい順序付けは非常に明白であり、正しいことを「感じる」だけだと思います。
@Wyatt Barnettsの答えと同様に、メソッドのいくつかのパラメーターまたは非常に明示的なパラメーター以外のものは、代わりにオブジェクトを渡すことをお勧めします。通常、これは更新/保守が簡単で、読みやすく、順序付けを気にする必要がありません。また、メソッドのパラメーターが多すぎるとコードの臭いがし、修正に役立つ一般的なリファクタリングパターンがあります。
明示的な例:
public int add(int left, int right)
{
return left + right;
}
これはかなり明確に定義された例であり、加算は可換であるため(順序は関係ありません)、そのまま使用します。
ただし、より複雑なものを追加する場合:
public SomeComplexReturnValue Calculate(int i, float f, string s, object o)
{
// do work here
}
になるでしょう:
public class SomeComplexInputForCalculation
{
public int i;
public float f;
public string s;
public object o;
}
public SomeComplexReturnValue Calculate(SomeComplexInputForCalculation input)
{
// do work here
}
お役に立てれば...
「重要な最初の」は、全体を意味しません。いくつかの規則があります。
呼び出し元のオブジェクト(多くの場合、名前付き送信者)を渡すと、それが最初になります。
リストにはある程度の流encyさがあるはずです。つまり、読む前に引数が何であるかを知る必要があります。例:
CopyFolder(string path、bool recursive);
再帰を最初に置いた場合、コンテキストがまだないため、混乱を招きます。すでにコピー(1)、フォルダー(2)についてである場合、引数再帰は意味を成し始めます。
また、これにより、IntelliSenseのような機能がうまく機能します。ユーザーは、引数を入力しながら学習し、メソッドとその機能の理解を深めます。同様に、オーバーロードは、等しいパーツに対して同じ順序を維持する必要があります。
その後、この点で「等しい」引数があることに気付く場合があり、順序を引数のタイプに依存させたいと思うかもしれません。行にいくつかの文字列があり、次にいくつかのブール値があるほうが見栄えがいいからです。あるレベルでは、これはスキルではなく芸術になります。
単一の引数で終わるために、すべての引数をオブジェクトにラップする必要があるというステートメントはあまり気にしません。それはただあなたを欺くだけです(メソッドをそれほど複雑にしません、それでもこれらの引数をすべて持っています、あなたはそれらを隠しました)。メソッドからメソッドへのセットを数回渡す場合、これはまだ便利かもしれませんが、リファクタリングははるかに簡単になりますが、デザイン的にはあなたが違いを生じているふりをしているだけです。何かを表す意味のあるオブジェクトになるのではなく、メソッドの宣言のリストと変わらない単なる引数の集まりになります。それはボブおじさんを幸せにしません。
MessageBox.Show
です。それも調べてください。