ヘルパー/ユーティリティクラスに関するこれらの簡単な質問に対する良い答えを見つけたことがありません。
静的メソッドを使用する代わりに、シングルトン(ステートレス)を作成するのはなぜですか?
オブジェクトに状態がない場合、オブジェクトインスタンスが必要なのはなぜですか?
多くの場合、シングルトンは、ある種のグローバル状態をアプリケーションに導入するために使用されます。 (正直に言うと、本当に必要以上に頻繁ですが、それはまた別のトピックです。)
ただし、stateless singletonでさえ有用な場合がいくつかあります。
lock
またはJava synchronized
ステートメントの同期オブジェクト。Toolkit.getDefaultToolkit()
メソッドは、正確なタイプがシステムに依存するシングルトンを返します。DBNull.Value
C#で。静的メソッドクラスの代わりにステートレスシングルトン、つまり Dependency Injection が使用されている場合があります。
直接使用しているユーティリティ関数のヘルパークラスがある場合、非表示の依存関係が作成されます。誰がどこで使用できるかを制御できません。ステートレスシングルトンインスタンスを介して同じヘルパークラスをインジェクトすると、使用する場所と方法を制御し、必要に応じて置換/モック/などを行うことができます。
それをシングルトンインスタンスにすることで、必要以上の種類のオブジェクトを割り当てないようにします(必要なのは1つだけなので)。
実際、私はここで言及されていない別の答えを見つけました:静的メソッドはテストするのが難しいです。
ほとんどのテストフレームワークは、インスタンスメソッドのモックに適していますが、その多くは静的メソッドのモックを適切に処理しません。
ほとんどのプログラミング言語では、クラスには多くの型システムが含まれていません。クラスは、その静的メソッドと変数とともにオブジェクトですが、多くの場合、インターフェイスを実装したり、他のクラスを拡張したりすることはできません。そのため、別のタイプのサブタイプにできないため、多態的に使用することはできません。たとえば、他のクラスのいくつかのメソッドシグネチャに必要なインターフェイスIFooable
がある場合、クラスオブジェクトStaticFoo
はIFooable
の代わりに使用できませんが、FooSingleton.getInstance()
は可能です(FooSingleton
がIFooable
を実装すると仮定)。
ハインジの答えについてコメントしたように、シングルトンはインスタンス化を制御するパターンであることに注意してください。 new Class()
をClass.getInstance()
に置き換えます。これにより、Class
の作成者はインスタンスをより詳細に制御でき、不必要なインスタンスの作成を防ぐことができます。シングルトンは、ファクトリパターンの非常に特殊なケースであり、そのように扱う必要があります。一般的な使用法は、グローバルレジストリを単に意図的に使用することはできませんので、むしろグローバルレジストリの特殊なケースになります。
グローバルヘルパー関数を提供する予定の場合、静的メソッドは問題なく機能します。クラスはクラスとして機能するのではなく、名前空間として機能します。高い凝集力を維持するか、最も奇妙なカップリングの問題が発生する可能性があります。
グリーツ
back2dos
どちらを使用するかにはトレードオフがあります。シングルトンには状態がある場合とない場合があり、オブジェクトを参照します。状態を保持せず、グローバルアクセスにのみ使用される場合は、これらのメソッドがより高速になるため、静的が優れています。しかし、オブジェクトとOOPコンセプト(継承ポリモーフィズム)を利用したい場合は、シングルトンの方が優れています。
たとえば、Java.lang.RuntimeはJavaのシングルトンクラスです。このクラスにより、JVMごとに異なる実装が可能になります。実装はJVMごとに1つです。このクラスが静的だった場合、JVMに基づいて異なる実装を渡すことはできません。
このリンクは本当に役に立ちました: http://javarevisited.blogspot.com/2013/03/difference-between-singleton-pattern-vs-static-class-Java.html ?
それが役に立てば幸い!!
私にとっては「シングルトンを使用したいオブジェクト状態、静的メソッドを使用したい関数」
それはあなたが望むものに依存します。オブジェクトの状態(たとえば、null
の代わりにNull状態のようなポリモーフィズム、またはデフォルトの状態)が必要な場合は常に、関数が必要なときに静的メソッドが使用します(入力を受信して出力を返す) 。
シングルトンの場合には、インスタンス化後は常に同じ状態になることをお勧めします。クローン化することも、設定する値を受け取ることもできません(たとえば、Javaのpropertiesファイルからの静的構成を除きます)。
追伸これら2つのパフォーマンスはミリ秒単位で異なるため、最初にArchitectureに注目してください。
シングルトンはステートレスではなく、グローバルな状態を保持します。
シングルトンを使用することで考えられるいくつかの理由は次のとおりです。