あなたが読んだすべての矛盾するアドバイスはある意味では理にかなっていますが、それらはすべて(異なる)仮定や曖昧な表現をしています。それは、「同じことを別の言葉で言う」タイプの区別の1つです。
メソッドは、状態を変更しない場合にのみ静的でなければなりません
「状態の変更」のあいまいさに注意してください。次の例はこのルールに(文字通り)違反していますが、ルールの(比喩的な)精神を保持しています。
public static void SetUserNameToBob(User u)
{
u.Name = "Bob";
}
これはUser
オブジェクトの状態を変更するため、実際には「状態を変更」します。
ただし、このメソッドは、それ自体の論理フローを決定するために特定の内部状態に依存しません(たとえばu.Name = currentlySelectedDefaultName()
、選択された名前が選択された状態であるため、違反になります)。そして、それが意味するところだと思います。内部状態は変更されません。
[メソッドは静的でなければなりません]その結果は、提供されたパラメーターにのみ依存します
前の項目を見てください、これはほとんど同じことを言っています。それが意味することはこれです:
public static string currentlySelectedDefaultName;
public static void SetUserNameToBob(User u)
{
u.Name = currentlySelectedDefaultName;
}
「現在のデフォルト」の名前は状態であるため、静的であってはならず、グローバル変数/メソッドであってはなりません。
2つの別々のスレッドが実行されている場合にどうなるかを考えてみます。1つはデフォルトで「Bob」に、もう1つはデフォルトで「Jim」にしたい場合です。それらは最終的に、大きなデバッグの問題や予期しない動作を引き起こす可能性がある値をめぐって争うことになります。
ただし、すべてのスレッドに独自のDefaultNameSetter
オブジェクトがある場合、それらは同じリソースをめぐって争うことはありません。
ただし、この投稿で最も投票数の多い回答には、可能な限り静的メソッドを使用する必要があると記載されています。
これは、try / failによるルールの強制のようなものです。このメソッドを静的に設定できますか?
- はい
=>
グッド!そのままにしている!
- いいえ
=>
これは、コードがどこかで非静的な値に依存しているため、静的にしないでください。
ジュラシックパークでジェフゴールドブラムを間接的に引用するには、それが可能であることを証明するだけで何かをする必要性を主張するべきではありません。
繰り返しになりますが、アプローチは必ずしも(または常に)間違っているわけではありませんが、メソッドはすでに論理的に可能な限り状態にとらわれないように記述されていると盲目的に仮定しています。
この方法論的アプローチに同意しても、プロジェクトが開発中でなくなった場合にのみ適用できます。プロジェクトがまだ開発中の場合、現在の方法が将来の実装のプレースホルダーになる可能性があります。Foo()
状態依存ロジックがまだ実装されていない場合、今日は静的にすることは可能ですが、明日は不可能にすることができます。
この投稿の回答の多くは、最も論理的なことは何でもすべきだと言っています。
まあ、彼らは間違っていません。しかし、これは「正しいことをする」と言っただけの小さな言い回しではありませんか?静的をいつ使用し、いつ静的を回避するかを既に知っているのでない限り、これは本当に役立つアドバイスではありません。キャッチ22です。
では、いつ静的を使用する必要がありますか?
お気づきのように、誰もがルールに同意するわけではなく、少なくともルールの言い回しに同意するわけではありません。ここで別の試みを追加しますが、これが別の標準を効果的に作成していることに注意してください。
心に留めておきます。
静力学は普遍的な真実です。
それがグローバル名前空間の目的です。アプリケーション層全体で正しいことです。
ここには滑りやすい議論があります。いくつかの例:
var myConfigKey = ConfigurationManager.AppSettings["myConfigKey"];
これは非常に明確な例です。アプリケーション構成は本質的に構成がアプリケーションに対してグローバルであることを意味するため、統計方式が保証されます。
bool datesOverlap = DateHelper.HasOverlap(myDateA_Start, myDateA_End, myDateB_Start, myDateB_End);
この方法は普遍的に正しいです。それは気にしないそのあなたが比較している日付。メソッドは日付の意味を気にしません。それらが雇用日であるか、契約日であるかどうかは...メソッドのアルゴリズムには関係ありません。
コンテキスト駆動型と状態駆動型の意味的な類似性に注意してください。どちらのソートも「非ユニバーサル」状態を指します。したがって、コンテキストの違いは状態に依存し、静的にするのには適していません。
var newPersonObject = Person.Create();
これは普遍的な真実です。同じ作成プロセスがアプリケーション全体で使用されます。
ただし、この線は不鮮明になる可能性があります。
var newManager = Person.CreateManager();
var newJanitor = Person.CreateJanitor();
技術的な観点からは、何も変わっていません。マネージャー(および管理人)は、アプリケーション全体で同じ方法で作成されます。ただし、これにより微妙に状態(マネージャー/管理人)が作成され、真実の普遍性が徐々に、しかし着実に損なわれます。
できますか?技術的な観点から。はい。
それを行うべきですか?それはあなたが純粋な原則を主張しているのか、それとも論理的完全性を無意味に追求しないようにするために妥協が必要であることを考慮に入れているのかという問題です。だから私は言うでしょう、それは問題を解決するためになされたものよりも、より大きな問題を作成しない場合。
オプションが拡大するにつれて(マネージャー、管理人、会計士、営業担当者など)、問題は大きくなります。十分に大きな問題の場合は、工場パターンが望ましいです。
オプションが2つしかなく、オプションのリストが増えると疑う理由がない場合は、静的作成メソッドで十分であると主張できます。反対する人もいるかもしれませんが、私も彼らの主張を理解しています。しかし、私は実践的であり、私のアプローチでは過度に完璧主義的ではありません。