web-dev-qa-db-ja.com

使用するたびにシングルトンまたはインスタンス化しますか?

私は、1つの既知のオブジェクトからデータを抽出し、それを他の既知のオブジェクトに配布するクラスを使用しています。そのクラスインスタンスに永続的な構成などは必要ありません。

そのクラスを singleton としてセットアップするか、必要なときに毎回インスタンス化するかをどのように決定すればよいですか?

14
bebbi

クラスに状態がない場合は、言語に応じて関数または静的メソッドに変換することを検討できます。

35
JacquesB

シングルトンはアンチパターンです と見なされることがあります。解決される問題が特にシングルトンパターンの使用を必要としない限り、一般的にそれを避けるのが最善です。

関数には状態や他の長期的な要件がないため、オブジェクトの即時の必要性もそこにはないと述べました。

無料の関数は、状態を持たず、シングルトンに関連する問題を引き起こさないため、最適です(または静的な関数または類似の言語とターゲット)。

フリー関数がオプションでない場合は、空のオブジェクト(データメンバーなし)が十分に近い2番目のオプションになるでしょう。


一般に、パターンを選択するときの私のアドバイスは、まずパターンが解決しようとしている問題と、パターンの制限と制約を理解することです。いったん理解されると、解決される問題がそのパターンの問題空間に該当する場合、そのパターンは使用の候補になります。

23
Niall

これらの「既知のオブジェクト」が何であるかをどのように判断しますか?コードでハードコードされている場合(つまり、オブジェクトが静的またはシングルトン自体)、静的メソッドを使用して処理を実行し、必要に応じてそれを呼び出すこともできます。

これらの既知のオブジェクトがクラス内部で状態と見なされない限り、なぜこのプロセスにクラス全体が必要になるのかわかりません。この場合、それが必要な頻度とそれを作成するコストに依存します。多くの労力を要し、シングルトンがおそらく最良です。

4
gbjbaanb

Niallの答えは適切で、受け入れられた答えは正しいと思いますが、シングルトンを使用する方法に少し加えたいと思います。

シングルトンパターンは、共産主義に少し似ています。紙の上では見た目は良いですが、人と混ぜるとバラバラになりがちです。

シングルトンパターンは本質的にアンチパターンではないということです。それのほとんどの(素朴な)実装は重要な側面をすくい取るか、または起こり得る問題を引き起こす傾向があります。

たとえば、C++では、メインループが始まる前のいつでも、グローバルに初期化されたシングルトンをほぼ割り当てることができます。この方法で複数のシングルトンを組み合わせると、それらが互いに相対的に初期化される順序がわかりません。クリーンアップの順序も同様に任意です(ただし、通常、初期化された順序の逆です)。 (これにはいくつかの基本的なルールがありますが、ほとんどは 鼻の悪魔 に任されています。)

グローバルで容易にアクセスできるオブジェクトも、最終的には God Class の領域に移る傾向があり、これは非常にアンチパターンです。 「私はすでにManagerクラスを持っているので、そこに貼り付けます」などのアイデアは簡単で、解決策は迅速です。これは Technical Debt の場合です。

正しく管理された制御されたシングルトンは非常に有用であり、問​​題を引き起こしませんが、人々が期待する傾向よりも正しくするのは難しいパターンです。最悪の部分は、教科書の例はシングルトンの本当に悪い習慣を教える傾向があるということです。


特定のケースでは、状態がなく、ロードまたはアンロードする必要がないため、オブジェクトは必要ありません。静的関数または同等の関数がニーズに合うはずです。

また、(shake fist)はコメントできないので、パターンが何を解決し、どこで機能するかを理解するためのNiallのポイントを次に説明します。 パターンを正しく実装することは、少なくとも正しいパターンを選択することと同じくらい重要であるため、それがどのように機能し、どのように実装するのが最善かを調査することもお勧めします。

3
XCompWiz