大文字のS「シングルトン」が適切かどうかについては...これを自問してください...
2番目のインスタンスが私のプログラムの死を引き起こすことは確実ですか?
(私は「特定の」と「死」を意味します。「可能性が高い」だけでなく、どのインスタンスが「公式」のインスタンスであるかについての混乱だけではありません。プログラムがクラッシュしたり、崩壊したり、ワームホールを開いたり、あなたの犬など、完全に2番目のインスタンスが存在するため、答えは「はい」です。確信が持てない場合は、確かな証拠が得られるまで「いいえ」と想定してください。)
答えが「はい」の場合、シングルトンを使用するための有効なケースがある可能性があります。そうでない場合は、それを誤用しているので、より良い解決策
があります。2番目のインスタンスを作成しないでください。
シングルトンを使用する理由はいくつかあります。
「オブジェクトをアプリ全体に渡さずに使用できるようにしたいと考えています。」何だと思う?あなたが持っているのは、栄光に満ちたグローバル変数です。そして、それがすべての世界に見えるように座っているよりも、あるクラスの腸に隠れているとき、それはさらに悪いことです。 グローバルを使用したい場合は、おかしなグローバルを使用してください。 ゲッターの後ろに隠して、人々が気付かないと思ってはいけません。
「私はこれらのうちの1つだけが必要です。」上記を参照。 必要なのは1つだけですか?1つだけ作成します。 あなたが今それを必要としているかどうかにかかわらず、あなたはそこにちょうど1つになるように強制する正当な理由がありますか?将来、別のものが必要な場合はどうなりますか?別のクラスを作成するのに苦労しただけでなく、おそらく1つだけが存在できるようにクラスを構築しました。また、元に戻すための「設計」がたくさんあります。
「言うことができるのは便利MySingleton.getInstance()
です。」ええ、あなたがテストを気にし始めるまで。を参照してください。呼び出すたびにMySingleton.getInstance()
、そのオブジェクトが存在できる唯一のタイプであるという仮定をもう1つ追加しました。単体テストをいじり始めた場合、テストはすべてその1つのインスタンスの動作、さらにはテストの実行順序に依存するため、ほとんど役に立ちません。グローバルでさえテスト容易性にとってそれほど悪くはありません、そしてそれはちょっとひどいです。(また、上記の「...アプリ全体に渡さずに」を参照してください。)
シングルトン問題の解決策は、一般的に依存性注入です。大きな言葉ですが、非常に単純な前提です。フレームワーク以外のバージョンは、基本的に、「オブジェクトがその仕事をするために必要な外部のものですか?コンストラクターに渡します」です。これを単純化できるとされるDIコンテナライブラリ/パッケージがありますが、それはすべて、オブジェクトを動かして自分で何かを見つけるのではなく、オブジェクトに何を使用するかを指示することを意味します。したがって、1つのインスタンスをそれを必要とするオブジェクトに渡すと、何も言う必要はありません。あるいは、そのオブジェクトがシングルトンであるかどうかMySingleton.
さえ気にする必要はありません。