のシングルトンパターンの完全に支払われたメンバーですGoFのパターンブックしかし、最近では開発者の世界によってかなり孤立しているようです。私はまだ特にたくさんのシングルトンを使います。ファクトリークラスそして、あなたがマルチスレッドの問題(実際には他のクラスのように)について少し注意を払わなければならない間、私はそれらがそれほどひどい理由を見ていません。
Stack Overflowは、特にシングルトンが悪であることに誰もが同意すると仮定しているようです。どうして?
「あなたの答えを支持してください。」事実、参照、または特定の専門知識「
Brian Buttonからの言い換え:
それらは一般的にグローバルなインスタンスとして使用されています、なぜそれはそれほど悪いのでしょうか?なぜなら、インターフェースを通してそれらを公開するのではなく、あなたのコードの中であなたのアプリケーションの依存関係を隠すからです。それを回避しないようにグローバルなものを作ることはコード臭。
彼らは単一責任原則:彼らが彼ら自身の創造とライフサイクルをコントロールするという事実のおかげで。
それらは本質的にコードを厳しくします結合した。これは、多くの場合、テスト中にそれらを取り出すのをかなり難しくします。
それらはアプリケーションの存続期間中は状態を伝えます。テストを注文する必要があるという状況に陥る可能性があるため、テストに再度ヒットすることになります。これは、単体テストには大きな問題です。どうして?なぜなら、各単体テストは互いに独立しているべきだからです。
シングルトンは一つの(そして唯一の)問題を解決します。
リソースの競合
いくつかのリソースがあれば
(1)単一のインスタンスしか持てません。
(2)その単一のインスタンスを管理する必要があります。
あなたには必要だシングルトン。
多くの例はありません。ログファイルは大きなものです。あなたはただ一つのログファイルを放棄したくはありません。あなたはそれを適切にフラッシュし、同期し、そして閉じたいです。これは、管理する必要がある単一の共有リソースの例です。
シングルトンが必要になることは稀です。彼らが悪いのは、彼らがグローバルそして彼らは、GoFの全額支払われたメンバーです。デザインパターン本。
あなたがグローバルを必要としていると思うとき、あなたは恐ろしいデザインミスをしているでしょう。
一部のコーディングスノブはそれらを単なる賛美されたグローバルとして見下しています。多くの人が嫌いなのと同じようにgoto声明を使用するという考えを憎む他の人がいるグローバル。私は何人かの開発者がこれを避けるために驚くべき長さになるのを見ました。グローバル彼らは失敗を認めるものとしてそれを使うことを考えたからです。奇妙だが本当だ。
実際にはシングルトンpatternは単なるプログラミング技法であり、概念のツールキットの一部です。時々あなたはそれが理想的な解決策であると思うかもしれないのでそれを使う。しかし、それを使うためにはデザインパターンそれがちょうどそれであるのでこれまでにそれを使用することを拒否するのと同じくらい愚かですグローバル。
GoogleのMisko Heveryには、まさにこのトピックに関する興味深い記事がいくつかあります。
シングルトンは病的嘘つきですシングルトンが依存関係の連鎖を把握し、アプリケーションを起動またはテストすることを困難にする可能性があることを示すユニットテストの例があります。それは虐待のかなり極端な例ですが、彼がしていることはまだ有効です。
シングルトンはグローバルな状態に過ぎません。グローバル状態はそれをあなたのオブジェクトがそれらのAPIで宣言されていないものをひそかに手に入れることができるようにし、その結果、シングルトンはあなたのAPIを病理学的嘘つきにします。
すべてのシングルトンがなくなったところ依存性注入によって、それらを必要とするコンストラクタへのインスタンスの取得が容易になったという点は、最初の記事で説明された悪いグローバルなシングルトンの背後にある根本的なニーズを軽減します。
私は混乱が人々がシングルトンパターンの本当の応用を知らないという事実によって引き起こされると思います。私はこれを十分に強調することはできません。シングルトンはではないグローバルをラップするパターンシングルトンパターンはそれを保証するためにのみ使われるべきです与えられたクラスのただ一つのインスタンス実行時に存在します。
彼らはグローバルにそれを使用しているので人々はシングルトンは悪だと思います。シングルトンが見下ろされているのは、この混乱のためです。シングルトンとグローバルを混同しないでください。それが意図されていた目的のために使用されるならば、あなたはシングルトンパターンから極端な利益を得るでしょう。
setInstance
しかし、それはほとんど問題ではありません。シングルトンもカプセル化についてのおかしいことや、変更可能なグローバル状態の何が悪いのかを知らなかったので、彼はすべての人にセッターを提供しました。シングル。フィールド。 (そして、はい、これは起こります。ロット。私がこれまでに見たことがあるほとんどすべてのシングルトンは、設計によって変更可能であり、しばしば恥ずかしいことにそうでした。) - cHaogoto
など作業多くの場合、率直に言って"動作"十分ではありません - 慣習的な知恵に反したい場合は、自分のアプローチがどのように行われているかを示すことができたほうがよいでしょう。より良い従来のソリューションよりも。シングルトンパターンについては、まだそのようなケースは見ていません。 - cHaogetInstance
または同様の名前の付いたメソッドで、2番目のインスタンスの存在を防ぎます。率直に言って、その時点で、あなたも同様に持っていないかもしれません1インスタンス。 - cHao
シングルトンに関するもう1つの悪い点は、それらを簡単に拡張できないことです。あなたは基本的に何らかの種類で構築する必要がありますデコレータパターンあなたが彼らの振る舞いを変えたいなら、あるいはそのようなこと。また、ある日、その1つのことを複数の方法で実行したい場合は、コードのレイアウト方法によっては、変更するのがかなり面倒な場合があります。
注意すべき1つのことは、シングルトンを使用する場合は、直接アクセスするのではなく、必要な人に渡してみることです。それ以外の場合は、シングルトンで行うことを複数の方法で行うことにします。シングルトンに直接アクセスする場合、各クラスが依存関係を埋め込むので、変更がかなり困難です。
だから基本的に:
public MyConstructor(Singleton singleton) {
this.singleton = singleton;
}
のではなく:
public MyConstructor() {
this.singleton = Singleton.getInstance();
}
このようなパターンは、依存性注入そして一般的には良いことだと考えられています。
他のパターンと同じように...それについて考えて、与えられた状況でのその使用が不適切であるかどうかを検討してください...規則は通常破られるように作られていますパターン何も考えずに何もしないで適用しないでください。
getInstance()
そして、(b)はもはや真実ではありません。 - cHaogetInstance()
シングルトンパターンと通常の参照との間の1つの有用な違いを効果的に排除しました。コードの他の部分に関しては、単一性はもはや特性ではありません。の発信者のみgetInstance()
これまでにいくつのインスタンスが存在するかを知っているか、気にする必要さえあります。呼び出し元が1人だけの場合は、呼び出し元に単純に参照を格納してそれを再利用させるよりも、クラスが確実に単一性を適用するための労力と柔軟性が高くなります。 - cHao
シングルトンパターンはそれ自体問題ではありません。問題は、オブジェクト指向のツールを使ってソフトウェアを開発している人々がオブジェクト指向の概念をしっかり理解していなくても、そのパターンがよく使われることです。この文脈でシングルトンが導入されると、それらは少しの使用のためにヘルパーメソッドを含む管理できないクラスに成長する傾向があります。
シングルトンもテストの観点から問題です。それらは孤立した単体テストを書くのを難しくする傾向があります。制御の反転(IoC)と依存性注入ユニットテストに向いているオブジェクト指向の方法でこの問題を克服することを意図したパターンです。
でごみ収集環境シングルトンはすぐにメモリ管理に関して問題になる可能性があります。
シングルトンが同期の問題と同様にボトルネックになる可能性があるマルチスレッドのシナリオもあります。
シングルトンは静的メソッドを使って実装されます。静的メソッドは、単調なテストをする人々によって避けられないのです。このサイトのほとんどの人はユニットテストを強く支持しています。それらを避けるための一般的に最も受け入れられている規約は制御の逆転パターン。
Singleton
クラス。しかし、それはテストプロセスを非常に複雑にします。一つには、今、あなたは自由にクラスをアンロードすることができる必要があります(ほとんどの言語で実際にはオプションではありません)、またはテストごとに新しいVMを起動します(read:テストは何千倍もかかるかもしれません)。 2人の場合は、しかし、への依存Singleton
テスト全体に漏れている実装の詳細です。 - cHao
それがなるとシングルトンも悪いですクラスタリング。それで、あなたはもうあなたのアプリケーションに "厳密に一つのシングルトン"を持っていません。
次のような状況を考えてください。開発者として、データベースにアクセスするWebアプリケーションを作成する必要があります。並行データベース呼び出しが互いに競合しないようにするために、スレッド・セーブを作成します。SingletonDao
:
public class SingletonDao {
// songleton's static variable and getInstance() method etc. omitted
public void writeXYZ(...){
synchronized(...){
// some database writing operations...
}
}
}
したがって、アプリケーションにはシングルトンが1つだけ存在し、すべてのデータベースがこの1つだけを通過していることが確実です。SingletonDao
。あなたの生産環境は今このようになります:
これまでのところすべて問題ありません。
では、Webアプリケーションの複数のインスタンスを1つのクラスタに設定したいとします。さて、あなたは突然次のようなものがあります。
それは奇妙に聞こえますが、今すぐあなたのアプリケーションに多くのシングルトンがあります。そしてそれはまさにシングルトンがあるべきではないということです:それの多くのオブジェクトを持つこと。この例に示すように、データベースに対して同期呼び出しを行いたい場合、これは特に悪いことです。
もちろん、これはシングルトンの悪い使い方の一例です。しかし、この例のメッセージは次のとおりです。アプリケーションにシングルトンのインスタンスが1つだけ存在するとは限りません。特にクラスタ化の場合はそうです。
独占は悪魔であり、非読み取り専用/可変状態のシングルトンは「本当の」問題です...
読んだあとシングルトンは病的嘘つきですで示唆されているようにジェイソンの答え私はこの小さなちょっとした一口を見つけました。どうやってシングルトンはしばしば誤用されます。
グローバルは悪いです:
- a。名前空間の競合が発生します
- b。それは不当な方法で国家を公開します
シングルトンになると
- a。それらを呼び出す明示的なオブジェクト指向の方法は、衝突を防ぎます。問題ではない
- b。状態のないシングルトンは(工場のように)問題にはなりません。状態を持つシングルトンは、ふたつのカテゴリに分類できます。不変であるか、一度書いてたくさん読む(config / propertyファイル)です。これらは悪くありません。リファレンスホルダーの一種である可変シングルトンは、あなたが話しているものです。
最後の声明で、彼はブログの「シングルトンは嘘つきだ」という概念に言及しています。
これはモノポリーにどのように当てはまりますか?
独占のゲームを開始するには、まず、
今、そうではない人のために本当に独占を果たした、これらの標準はせいぜい理想的です。独占はお金に関係しているので、独占の敗北は飲み込むのが難しいです。負けた場合、残りのプレイヤーがゲームを終えるのを注意深く見守る必要があります。そのため、通常、他の人を犠牲にして一部のプレーヤーの自己利益に応えるために、ある時点でルールがねじれます。
だから、あなたは友達のボブ、ジョー、そしてエドと独占しています。あなたは迅速にあなたの帝国を築き、指数関数的な割合で市場占有率を消費しています。あなたの対戦相手は弱っていて、あなたは(比喩的に)血をかぎ始めます。あなたの相棒Bobは彼のお金の全てを可能な限り多くの低価値の物件をグリッドロックするのに投入しました、しかし彼は彼が期待したように高い投資収益率を得ていません。ボブは不運の一撃としてあなたのボードウォークに着地し、ゲームから切り出されます。
今度はゲームは友好的なダイスロールから重大なビジネスに行きます。ボブは失敗の例にされました、そして、ジョーとエドは「あの男」のように終わることを望みません。ですから、あなたが主役になって、突然あなたは敵になるでしょう。 JoeとEdは、テーブルの下での取引、背後でのお金の投入、過小評価されたハウススワッピング、そして一般的に、プレーヤーの1人がトップに上がるまであなたを弱めるための何かを練習し始めます。
それから、それらのうちの1つが勝つ代わりに、プロセスは最初から始まります。突然、有限の一連のルールが動く標的となり、ゲームはSurvivor以降のすべての高評価のリアリティTV番組の基盤を構成する社会的相互作用のタイプに退化します。なぜ、ルールが変更されているのか、そしてそれらがどのように/なぜ/何を表すべきかについてコンセンサスがないからです。さらに重要なことに、決定を下す人は誰もいません。その時点で、ゲーム内のすべてのプレイヤーは自分のルールを作成しており、2人のプレイヤーが疲れきってしゃべりに追いついてゆっくりとあきらめることができなくなります。
したがって、ゲームのルールブックがシングルトンを正確に表している場合、独占ルールブックは悪用の例になります。
これはプログラミングにどのように当てはまりますか。
可変のシングルトンが存在する明白なスレッド安全性と同期の問題の他に... 1セットのデータがある場合、それは複数の異なるソースによって同時に読み取り/操作される可能性があり、アプリケーションの実行期間中に存在します。 「ここでは適切な種類のデータ構造を使用していますか」と尋ねて尋ねるのは、おそらくいい機会です。
個人的には、プログラマがシングルトンをアプリケーション内のある種のねじれクロススレッドデータベースストアとして使用することによってシングルトンを悪用するのを見たことがあります。コードを直接処理したところ、(スレッドセーフにするために必要なすべてのスレッドロックのために)遅いことと(同期バグの予測不可能/断続的な性質のために)悪夢のためであったことを証明できます。 「製造」条件下でテストすることはほぼ不可能です。確かに、パフォーマンスの問題のいくつかを克服するためにポーリング/シグナリングを使用してシステムを開発した可能性がありますが、それでテストの問題は解決しません。 /スケーラブルな方法。
シングルトンはのみシングルトンが提供するものが必要な場合のオプション。オブジェクトの書き込み専用の読み取り専用インスタンス。その同じ規則は、オブジェクトのプロパティ/メンバにもカスケードするはずです。
Singleton.getInstance()
。リフレクションをサポートする言語は、One True Instanceが格納されているフィールドを設定することでそれを回避できるかもしれません。ただし、IMOでは、別のクラスの非公開国で詐欺に遭遇すると、テストの信頼性が少し低下します。 - cHao
他の答えとは異なり、私はシングルトンの何が悪いのかについて話すのではなく、それらが正しく使われたときにどれほど強力で素晴らしいかをあなたに見せたいのです!
MyModel myModel = Factory.inject(MyModel.class);
あなたはマッピングすることができますMyModel
にTestMyModel
いつでもどこでもそれを継承するクラスMyModel
あなたが得るだろう注入されますTestMyModel
読みました。私がタイトルシングルトンで述べたように単一インスタンスについてではありません。
また、過度に使用されていると感じ、クラスの唯一のインスタンスが実際には必要とされていない状況では不要な制限が導入されると考える一部の人々にとってはアンチパターンとも考えられます。[1] [2] [3] [4]
参考文献(記事からの関連する参考文献のみ)
シングルトンがどのように悪いのかについての私の答えは、常に「彼らは正しくするのは難しい」です。言語の基本的な構成要素の多くはシングルトン(クラス、関数、名前空間、さらには演算子)であり、コンピューティングの他の側面(localhost、デフォルトルート、仮想ファイルシステムなど)の構成要素でもあり、偶然ではありません。彼らは時々トラブルとフラストレーションを引き起こしますが、彼らはまた多くのことがLOTにより良く働くようにすることができます。
私が見ている2つの最大の失敗は、次のとおりです。シングルトンクロージャを定義できませんでした。
彼らは基本的にそうであるので、誰もがグローバルとしてシングルトンについて話します。しかし、グローバルの悪い点の多く(残念ながら、全部ではありません)は、本質的にグローバルであることからくるのではなく、それをどのように使用するかです。シングルトンにも同じことが言えます。 「単一インスタンス」が「グローバルにアクセス可能」という意味である必要は実際にはないほどです。それはもっと自然な副産物であり、私たちがそれから来ることを私たちが知っているすべての悪いことを考えると、私たちはグローバルなアクセシビリティを悪用するためにそんなに急いでいるべきではありません。プログラマがシングルトンを見ると、常にそのインスタンスメソッドを通して直接アクセスするように見えます。代わりに、他のオブジェクトと同じようにナビゲートする必要があります。ほとんどのコードは、シングルトンを扱っていることを認識すべきではありません(疎結合、そうでしょう?)。それがグローバルであるようにほんの少しのコードだけがオブジェクトにアクセスするならば、多くの害は元に戻されます。インスタンス関数へのアクセスを制限してそれを強制することをお勧めします。
シングルトンの文脈も非常に重要です。シングルトンの定義的な特徴は「ただ1つ」ということですが、実際のところ、それはある種のコンテキスト/名前空間の中では「ただ1つ」であるということです。それらは通常、スレッド、プロセス、IPアドレス、またはクラスタごとに1つですが、プロセッサ、マシン、言語の名前空間/クラスローダ/その他、サブネット、インターネットなどごとに1つにすることもできます。
もう1つの、それほど一般的ではない間違いは、Singletonのライフスタイルを無視することです。 1つしかないからといって、シングルトンが「常にあった、そしてこれからも」全能であることを意味するわけでも、一般的に望ましいことでもありません(開始および終了のないオブジェクトはコード内のあらゆる種類の有用な仮定に違反し、採用されるべきです)最も絶望的な状況の中で。
これらの間違いを避けても、Singletonsは依然としてPITAになる可能性があります。最悪の問題の多くが大幅に軽減されるのを見る準備ができています。 Javaシングルトンを想像してみてください。これは、クラスローダーごとに1回明示的に定義され(スレッドセーフティポリシーが必要です)、定義および作成メソッドとそれらが呼び出されるタイミングと方法を決定するライフサイクルを持ちます。パッケージ保護なので、通常は他の非グローバルオブジェクトを介してアクセスされます。まだ潜在的な問題の原因ですが、確かにはるかに少ない問題です。
悲しいことに、シングルトンのやり方の良い例を教えるよりはむしろ。私たちは悪い例を教え、プログラマがしばらくそれらを使わないようにし、そしてそれらが悪いデザインパターンであることを伝えます。
シングルトン自体が悪いというわけではありませんが、GoFのデザインパターンは悪いです。実際に有効な唯一の議論は、GoFデザインパターンはテストに関しては意味がありません、特にテストが並行して実行される場合です。
以下の手段をコードに適用する限り、クラスの単一インスタンスを使用することは有効な構成です。
シングルトンとして使用されるクラスがインタフェースを実装していることを確認してください。これにより、スタブやモックを同じインターフェースを使って実装することができます。
シングルトンがスレッドセーフであることを確認してください。それは与えられたことです。
シングルトンは本質的に単純で、過度に複雑ではないはずです。
アプリケーションの実行時に、シングルトンを特定のオブジェクトに渡す必要がある場合は、そのオブジェクトを構築するクラスファクトリを使用し、そのクラスファクトリにそれを必要とするクラスにシングルトンインスタンスを渡します。
テスト中および確定的な動作を保証するために、実際のクラス自体、またはその動作を実装するスタブ/モックのいずれかとして別のインスタンスとしてシングルトンクラスを作成し、それを必要とするクラスにそのまま渡します。テスト中にシングルトンを必要とするテスト中のオブジェクトを作成するクラスファクタは、その単一のグローバルインスタンスを渡すため、使用しないでください。目的が無効になります。
私たちのソリューションではシングルトンを使用してきましたが、それは並列テストランストリームにおける決定論的な振る舞いを保証するテストが可能です。
ヴィンスハストンこれらの基準を持っていて、それは私には妥当と思われます
シングルトンは、次の3つの基準がすべて満たされている場合にのみ考慮する必要があります。
- 単一インスタンスの所有権を合理的に割り当てることはできません
- 遅延初期化が望ましい
- グローバルアクセスは、他の方法では提供されていません。
単一インスタンスの所有権、いつ、どのように初期化が行われるのか、およびグローバルアクセスが問題にならないのであれば、Singletonはあまり面白くありません。
私は受け入れられた答えの中の4つの点に対処したいのですが、うまくいけば誰かが私が間違っている理由を説明することができます。
コード内で依存関係を隠すのはなぜ悪いのでしょうか。すでに何十もの隠れた依存関係(Cランタイム呼び出し、OS API呼び出し、グローバル関数呼び出し)があり、シングルトンの依存関係は簡単に見つけることができます(instance()を検索)。
「回避しないようにグローバルなものを作るのはコードの匂いです。」なぜシングルトンをコードの臭いにするのを避けるために何かを渡していないのですか?
シングルトンを回避するためだけに、コールスタック内の10個の関数を介してオブジェクトを渡す場合は、それほど素晴らしいことでしょうか。
単一責任の原則:これは少しあいまいであり、責任の定義によります。関連する質問は、なぜこれを追加するのでしょうか特定階級問題に対する「責任」?
オブジェクトをクラスに渡すと、そのオブジェクトをクラス内からシングルトンとして使用するよりも密接に結合されるのはなぜですか。
それはなぜ国家が存続する期間を変えるのですか?シングルトンは手動で作成または破棄することができます。そのため、コントロールはまだ存在しており、有効期間を非シングルトンオブジェクトの有効期間と同じにすることができます。
単体テストについて
シングルトンは純粋主義者の観点からは良くありません。
実用的な観点からは、シングルトンは、開発時間と複雑さのトレードオフです。。
アプリケーションがそれほど変更されないことがわかっている場合は、それらを使用しても問題ありません。要件が予期しない方法で変更された場合は、作業内容をリファクタリングする必要があるかもしれません(ほとんどの場合、これで問題ありません)。
シングルトンも時々複雑になる単体テスト。
パターンが本当に単一のモデルのいくつかの側面に使用されていると仮定すると、そのパターンに本質的に問題はありません。
私は、反動がその過剰利用のせいであると信じています。それは、理解し、実行するのが最も簡単なパターンであるという事実によるものです。
シングルトンはパターンであり、他のツールと同じように使用または悪用される可能性があります。
シングルトンの悪い部分は、一般的にはユーザーです(または、それがするように設計されていないことに対するシングルトンの不適切な使用を言うべきです)。最大の違反者は偽のグローバル変数としてシングルトンを使用しています。
ロガーやデータベース接続など、シングルトンを使用してコードを作成したときに、複数のログまたは複数のデータベースが必要であることがわかった場合は、問題があります。
シングルトンはそれらから普通のオブジェクトへ移動することを非常に困難にします。
また、スレッドセーフではないシングルトンを書くのは簡単すぎます。
シングルトンを使用するのではなく、必要なすべてのユーティリティオブジェクトを機能ごとに渡す必要があります。このように、それらすべてをヘルパーオブジェクトにラップすれば、単純化することができます。
void some_class::some_function(parameters, service_provider& srv)
{
srv.get<error_logger>().log("Hi there!");
this->another_function(some_other_parameters, srv);
}
シングルトンに関する問題は、スコープの拡大という問題です。カップリング。単一のインスタンスにアクセスする必要がある状況がいくつかあることを否定することはできません。それは他の方法でも達成できます。
私は今の周りに設計することを好む制御の逆転(IoC)コンテナを使用して、コンテナによってライフタイムを制御できるようにします。これにより、単一のインスタンスが存在するという事実に気付かないように、インスタンスに依存するクラスの利点が得られます。シングルトンの寿命は将来変更することができます。私が最近遭遇したそのような例は、シングルスレッドからマルチスレッドへの簡単な調整でした。
あなたがそれを単体テストしようとするときそれがPIAならばそれはあなたがそれをデバッグしようとするとき、それはPIAに行くつもりです、バグ修正または強化。
これはまだ誰も言っていないシングルトンに関するもう一つのことです。
ほとんどの場合、「シングルトン性」は、そのインターフェースの特性ではなく、何らかのクラスの実装の詳細です。コントロールコンテナの反転は、この特性をクラスユーザから隠すかもしれません。あなたのクラスをシングルトンとしてマークする必要があります。@Singleton
例えばJavaのアノテーション)それだけです。残りはIoCCが行います。アクセスはすでにIoCCによって管理されているため、シングルトンインスタンスへのグローバルアクセスを提供する必要はありません。したがって、IoCシングルトンに問題はありません。
IoCシングルトンとは反対側のGoFシングルトンは、getInstance()メソッドを介してインタフェース内の "シングルトン性"を公開することになっているため、上記のすべての問題を抱えています。
シングルトンは悪くありません。グローバルにユニークではなく、グローバルにユニークなものを作るときにだけ悪いのです。
ただし、「アプリケーションスコープサービス」(コンポーネントを対話させるメッセージングシステムについて考える)があります - シングルトン用のこのCALLS、「MessageQueue」 - メソッド「SendMessage(...)」を持つクラス。
その後、いたるところから次のことができます。
MessageQueue.Current.SendMessage(new MailArrivedMessage(...));
そしてもちろん、
MessageQueue.Current.RegisterReceiver(this);
IMessageReceiverを実装するクラス内
スレッドセーフではないオブジェクトをシングルトンパターンに入れる人が多すぎます。私はDataContextの例を見ました(LINQ to SQLDataContextはスレッドセーフではなく、純粋に作業単位オブジェクトであるという事実にもかかわらず、シングルトンパターンで行われます。
これらは基本的にオブジェクト指向のグローバル変数なので、通常は不要になるようにクラスを設計できます。
複数の人(またはチーム)が類似または同一の解決策にたどり着くと、パターンが出現します。多くの人がまだシングルトンをオリジナルの形で使ったりファクトリテンプレートを使ったりしています(AlexandrescuのModern C ++ Designでよく議論されています)。オブジェクトの存続期間を管理する際の並行性と困難さが主な障害です。
すべての選択肢と同様に、シングルトンは浮き沈みの公正なシェアを持っています。私はそれらが適度に、特にアプリケーションの寿命を生き残ったオブジェクトのために使用できると思います。彼らが世界的に似ている(そしておそらくそうである)という事実は、おそらく純粋主義者を後押ししている。
第一に、クラスとその共同研究者は、子供に焦点を合わせるのではなく、まず意図した目的を実行する必要があります。ライフサイクル管理(インスタンスが範囲外になったときにインスタンスが作成されたとき)は、クラッドの責任の一部になるべきではありません。これに関して受け入れられているベストプラクティスは、依存性注入を使用して依存性を管理するための新しいコンポーネントを作成または構成することです。
ソフトウェアはより複雑になることが多く、異なる状態を持つ「シングルトン」クラスの複数の独立したインスタンスを持つことは理にかなっています。このような場合は、シングルトンを取得するためだけにコードをコミットするのは間違っています。 Singleton.getInstance()を使用しても、小規模で単純なシステムでは問題ないかもしれませんが、同じクラスの異なるインスタンスが必要な場合は機能しません。
どのクラスもシングルトンと考えるべきではありませんが、むしろそれはその使用法や扶養家族の設定にどのように使用されるかの応用であるべきです。厄介なことにはこれは問題ではありません。ファイルパスは問題にならないと言うだけでなく、DIを使用してより適切な方法でそのような依存関係を管理する必要があります。
シングルトンがテストで引き起こす問題は、ハードコーディングされた単一の使用例/環境の症状です。テストスイートと多くのテストはそれぞれ個別のもので、シングルトンのハードコーディングと互換性のないものを分離しています。