web-dev-qa-db-ja.com

シングルトン実装ではなく静的クラスを選択するのはなぜですか?

静的対。シングルトンの質問は、SOで何度も議論されてきました。
しかし、すべての回答は、シングルトンの多くの利点を指摘しています。
私の質問は-シングルトンに対する静的クラスの利点は何ですか?毎回シングルトンを選択してみませんか?

30
Elad

静的クラスは、ボックス内の技術ツールであり、基本的には言語機能です。

シングルトンはアーキテクチャの概念です。

シングルトンの概念を実装する手段として静的クラスを使用できます。または、他のアプローチを使用することもできます。

C#の静的クラスでは、注意しないと2つの潜在的危険があります。

  • 要求されたリソースは、アプリケーションの有効期間が終了するまで解放されません
  • 静的変数の値は、アプリケーション内で共有されます。これらの値は特定のアプリケーションドメインに存在するサイトのすべてのユーザー間で共有されるため、ASP.NETアプリケーションには特に適していません。
40
user151323

から [〜#〜] msdn [〜#〜]

静的クラスとクラスメンバーは、クラスのインスタンスを作成せずにアクセスできるデータと関数を作成するために使用されます。静的クラスメンバーを使用して、オブジェクトIDに依存しないデータと動作を分離できます。データと関数は、オブジェクトに何が起こっても変更されません。静的クラスは、オブジェクトIDに依存するデータまたは動作がクラスにない場合に使用できます。

重要な点は、静的クラスdo not require an instance reference。また、静的クラスは言語とコンパイラによって特に有効になっていることに注意してください。

シングルトンクラスは、 シングルトン デザインパターンを実装するユーザーコードクラスです。シングルトンの目的はrestrict instantiation of an class to a single instance

すべての静的クラスをシングルトンとしてコーディングした場合、使用するたびにクラスをインスタンス化する必要があります。

つまり.

Console.WriteLine('Hello World');

になります

Console c = Console.getInstance();
c.WriteLine('Hello World');
23
rism

どちらも(一般的に)貧弱な解決策だと思います。静的クラスにはいくつかのユースケースがあり、主に単純なユーティリティクラスです(C#3.0の拡張メソッドが思い浮かびます)。ただし、ある程度複雑になると、テスト容易性の問題が発生し始めます。

クラスAが静的クラスBに依存しているとします。クラスAを分離してテストしたいとします。それは難しいです。

だからあなたはシングルトンで行きます。同じ問題があります。クラスAはシングルトンBに依存しています。クラスAを単独でテストすることはできません。

クラスBに他の依存関係(データベースへのアクセスなど)がある場合、または変更可能(他のクラスがグローバル状態を変更できる)の場合、問題は悪化します。

IoC( 制御の反転 )コンテナライブラリは、この問題の1つの解決策です。プレーンオールドクラスを長寿命として定義できます。モックライブラリと組み合わせると、コードを非常にテストしやすくすることができます。

9
TrueWill

静的クラスの実装ははるかに簡単です-静的フィールドのランタイムの保証された1回限りの初期化に依存する代わりに、ナイーブなロックスキームを採用するC#のスレッドセーフシングルトンで多くの試みを見てきました(オプションでインスタンス化を遅らせるためにネストされたクラス内)。

それ以外に、特定のインターフェイスを実装するオブジェクトへの参照を渡す必要がある場合、その「実装」がシングルトンである必要がある場合、シングルトンは優れていると思います。これは静的クラスでは実行できません。

6

私が言及していない考慮事項の1つは、クラスのインスタンス(シングルトン、または同等のDI)を使用するソリューションを優先すると、コードの他のユーザーが拡張メソッドを定義できるクラスを提供できることです-拡張メソッドのみthisパラメーターとして非静的クラスを操作します。言い換えれば、次のような行がある場合:

GlobalSettings.SomeMethod();

次に、構文的にGlobalSettingsを介してアクセスできるのは、指定したメンバーだけです。対照的に、GlobalSettingsがインスタンス(シングルトンまたはその他)の場合、コンシューマーは独自の拡張機能をGlobalSettingsに追加できますが、それ以外の場合は追加できません。

application.GlobalSettings.CustomSomethingOrOther();

または

GlobalSettings.Instance.CustomSomethingOrOther();
2
Kirk Woll