質問

シングルトンパターンは、 GoF パターンブックですが、最近は開発者の世界からかなり孤立しているようです。特にファクトリクラスには、まだ多くのシングルトンを使用しています。マルチスレッドの問題(実際には他のクラスと同様)に少し注意を払うと、なぜそんなにひどいのかわかりません。

特に、スタックオーバーフローは、シングルトンが悪であることに誰もが同意することを前提としているようです。なぜですか?

" 事実、参考資料、または特定の専門知識"

で回答をサポートしてください
役に立ちましたか?

解決

ブライアンボタンからの言い換え:

  1. これらは一般的にグローバルインスタンスとして使用されますが、なぜそんなに悪いのですか?インターフェースを介して公開するのではなく、コードのアプリケーションの依存関係を非表示にするためです。何かをグローバルに渡さないようにすることは、コードの匂いです。

  2. 彼らは単一責任原則に違反しています:彼らが管理しているという事実のために独自の作成とライフサイクル。

  3. これらは本質的にコードをカップルに厳密に結び付けます。これにより、多くの場合、テスト中にそれらを偽造することがかなり難しくなります。

  4. アプリケーションの存続期間中、状態を保持します。テストを注文する必要がある状況に陥ることがあるため、テストへの別のヒットは、単体テストにとっては大したことではありません。どうして?各ユニットテストは互いに独立している必要があるためです。

他のヒント

シングルトンは1つの(そして唯一の)問題を解決します。

リソースの競合。

リソースがある場合

1 )は単一のインスタンスのみを持つことができ、

2 )その単一インスタンスを管理する必要があります、

シングルトンが必要です。

多くの例はありません。ログファイルは大きなものです。単一のログファイルだけを破棄する必要はありません。適切にフラッシュ、同期、および閉じたい場合。これは、管理する必要がある単一の共有リソースの例です。

シングルトンが必要になることはまれです。彼らが悪い理由は、彼らがグローバルのように感じており、完全に支払い済みだからです。 GoF デザインパターン ブックのメンバー。

グローバルが必要だと思うとき、おそらくひどい設計ミスを犯しているでしょう。

一部のコーディングスヌーブは、それらを単なるグローバライズされたグローバルとして見下しています。多くの人が goto ステートメントを嫌うのと同じように、これまで global を使用するという考えを嫌う人もいます。いくつかの開発者は、失敗を容認するものとして使用することを検討したため、グローバルを回避するために途方もない長さになることを見てきました。奇妙だが真実。

実際には、 Singleton パターンは、概念のツールキットの有用な一部である単なるプログラミング手法です。時々あなたはそれが理想的な解決策であると思うかもしれないのでそれを使用してください。ただし、デザインパターンの使用を自慢できるように使用するのは、グローバルであるため、これを使用することを拒否するのと同じくらい愚かです。

GoogleのMisko Heveryには、まさにこのトピックに関する興味深い記事があります...

シングルトンは病理学的嘘つきですにはユニットがありますシングルトンが依存関係チェーンの把握とアプリケーションの起動またはテストを困難にする方法を示すテスト例。それは虐待のかなり極端な例ですが、彼が指摘するポイントはまだ有効です:

  

シングルトンは、グローバルな状態にすぎません。グローバル状態は、オブジェクトがAPIで宣言されていないものを密かに取得できるようにします。その結果、シングルトンはAPIを病理学的嘘つきにします。

すべてのシングルトンがなくなった場所は、依存性注入により、インスタンスを必要とするコンストラクターにインスタンスを簡単に取得できるようになったことを示しています。

混乱は、人々がシングルトンパターンの実際の応用を知らないという事実によって引き起こされると思います。私はこれを十分に強調することはできません。シングルトンは、グローバルをラップするパターンではありません 。シングルトンパターンは、実行時に特定のクラスのインスタンスが1つだけ存在することを保証するためにのみ使用する必要があります

人々はシングルトンをグローバルに使用しているため、シングルトンは悪だと考えています。シングルトンが軽lookedされているのは、この混乱のためです。シングルトンとグローバルを混同しないでください。意図された目的で使用された場合、シングルトンパターンから大きなメリットを得ることができます。

シングルトンの悪い点の1つは、シングルトンを簡単に拡張できないことです。基本的に、何らかのデコレーターパターンなどを変更する場合は、これらを組み込む必要があります。動作。また、ある日、その1つのことを複数の方法で行いたい場合、コードのレイアウト方法によっては、変更するのがかなり苦痛になる場合があります。

注意すべき点は、シングルトンを使用する場合は、シングルトンが直接アクセスするのではなく、必要な人に渡すようにしてください...そうでない場合、シングルトンが行うことを複数の方法で行うことを選択した場合、シングルトンに直接アクセスする場合、各クラスが依存関係を埋め込むため、変更するのはかなり困難です。

基本的に:

public MyConstructor(Singleton singleton) {
    this.singleton = singleton;
}

ではなく:

public MyConstructor() {
    this.singleton = Singleton.getInstance();
}

この種のパターンは、依存性注入と呼ばれ、一般的に良いと考えられています。

ただし、パターンのように...考えてみて、与えられた状況での使用が不適切かどうかを検討してください...規則は通常破られるように作られており、パターンは意図せずに無制限に適用すべきではありません。

シングルトンパターン自体は問題ではありません。問題は、オブジェクト指向ツールを使用してソフトウェアを開発する人々が、オブジェクト指向の概念をしっかりと把握していない場合に、パターンがよく使用されることです。このコンテキストでシングルトンが導入されると、ほとんど使用されないヘルパーメソッドを含む管理不能なクラスに成長する傾向があります。

シングルトンは、テストの観点からも問題です。それらは孤立した単体テストを書くのを難しくする傾向があります。 制御の反転 (IoC)および 依存性注入 は、単体テストに役立つオブジェクト指向の方法でこの問題を克服するためのパターンです。

収集されたゴミ環境では、シングルトンがすぐに問題になります。メモリ管理。

シングルトンがボトルネックや同期の問題になる可能性があるマルチスレッドシナリオもあります。

静的メソッドを使用してシングルトンが実装されます。静的メソッドは、モックやスタブ化ができないため、ユニットテストを行う人々によって回避されます。このサイトのほとんどの人は、単体テストの大きな支持者です。それらを避けるために一般的に最も受け入れられている慣例は、制御の反転パターンを使用することです。

シングルトンは、クラスタリングに関しても悪いです。そのため、「シングルトンが1つだけ」ではないためです。アプリケーションでもう。

次の状況を考慮してください。開発者として、データベースにアクセスする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. グローバル変数として簡単に(ab)使用されます。
  2. シングルトンに依存するクラスは、単体での単体テストが比較的困難です。

モノポリーは悪魔であり、非読み取り専用/可変状態のシングルトンは「本当の」問題です...

シングルトンは病理学的嘘つきを読んだ後ジェイソンの答えで示唆されているように、方法の最良の例を提供するこのちょっとしたヒントに出会いましたシングルトンはしばしば誤用されます。

  

グローバルが悪い理由:

     
      
  • a。名前空間の競合が発生します
  •   
  • b。状態を不当な方法で公開します
  •   
     

シングルトンに関しては

     
      
  • a。それらを呼び出す明示的なオブジェクト指向の方法は、競合を防ぎます。問題ではない
  •   
  • b。 (工場のような)状態のないシングルトンは問題ではありません。状態のあるシングルトンは、再び不変であるか、一度だけ書き込み、多くを読み取る(構成/プロパティファイル)の2つのカテゴリに分類されます。これらは悪くありません。参照ホルダーの一種である可変シングルトンは、あなたが言っているものです。
  •   

最後の声明では、彼はブログの「シングルトンは嘘つきだ」という概念に言及しています。

これはモノポリーにどのように適用されますか

独占ゲームを開始するには、まず:

  • 最初にルールを確立して、全員が同じページにいるようにします
  • 全員がゲームの開始時に平等なスタートを与えられます
  • 混乱を避けるため、1組のルールのみが提示されます
  • ゲーム全体でルールを変更することはできません

今、独占を本当にプレイしていない人にとって、これらの基準は最高の状態で理想的です。独占の敗北は飲み込むのが難しい。なぜなら、独占は金銭に関するものだからだ。もし負けた場合、他のプレイヤーがゲームを終了するのをじっくりと見る必要があり、損失は通常迅速で押しつぶされる。そのため、通常、ある時点でルールがねじれ、一部のプレーヤーの自己利益を他のプレーヤーを犠牲にして提供します。

つまり、あなたは友人のボブ、ジョー、エドと独占しているのです。急速に帝国を築き、指数関数的に市場シェアを消費しています。敵は弱体化しており、血の臭いがし始めます(具象的に)。相棒のボブは、すべてのお金をできるだけ多くの低価値資産に集中させましたが、期待したほど高い投資収益率を得ていません。運が悪いとボブはボードウォークに着地し、ゲームから除外されます。

ゲームは、フレンドリーなサイコロから本格的なビジネスに移行しました。ボブは失敗の例にされており、ジョーとエドは「あの男」のようにはなりたくない。だから、あなたが主役であるあなたは、突然、敵になります。ジョーとエドは、テーブルの下での取引、バックインザバックのマネーインジェクション、過小評価されたハウススワッピングなどを練習し始めます。

次に、そのうちの1人が勝つ代わりに、プロセスが最初から始まります。突然、限られた一連のルールが動いている標的になり、ゲームは、Survivor以降のすべての高評価の現実のテレビ番組の基盤を構成するような社会的相互作用のタイプに退化します。理由は、ルールが変化しており、どのように/なぜ/何を表すべきかについてコンセンサスがないためです。さらに重要なことは、決定を下す人がいないことです。ゲームのすべてのプレイヤーは、その時点で、2人のプレイヤーが疲れすぎてシャレードを維持し、ゆっくりとあきらめるまで、独自のルールと混乱を続けています。

したがって、ゲームのルールブックがシングルトンを正確に表している場合、独占ルールブックは虐待の例になります。

これはプログラミングにどのように適用されますか

明白なスレッド安全性と同期の問題を除き、tha

シングルトンは単一のインスタンスに関するものではありません!

他の回答とは異なり、シングルトンの何が問題なのかについては説明しませんが、正しく使用するとどれだけパワフルで素晴らしいかをお見せします!

  • 問題:シングルトンはマルチスレッド環境の課題になる可能性があります
    解決策:シングルスレッドブートストラッププロセスを使用して、シングルトンのすべての依存関係を初期化します。
  • 問題:シングルトンをモックするのは難しい。
    解決策:メソッド工場のパターンを使用してモックを作成します
    MyModel myModel = Factory.inject(MyModel.class); MyModel を継承する TestMyModel クラスにマッピングできます。 MyModel がインジェクトされるすべての場所で、 TestMyModel instreadを取得できます。 。
  • 問題:シングルトンは決して破棄されないため、メモリリークを引き起こす可能性があります。
    解決策:廃棄してください!アプリにコールバックを実装して、シングルトンを適切に破棄します。シングルトンにリンクされているデータをすべて削除し、最後にファクトリから削除します。

タイトルで述べたように、シングルトンは単一インスタンスに関するものではありません。

  • シングルトンは読みやすさを向上させます:クラスを見て、どのシングルトンがインジェクションされたかを確認して、依存関係を把握できます。
  • シングルトンによりメンテナンスが改善されます:シングルトンインジェクションを削除したクラスから依存関係を削除したら、依存関係を移動した他のクラスの大きなリンクを編集する必要はありません。 (これは私にとって臭いコードです @Jim Burger
  • シングルトンによりメモリとパフォーマンスが向上します:アプリケーションで何かが発生し、コールバックの長いチェーンが必要になると、シングルトンを使用することでメモリとパフォーマンスが無駄になります。男性、およびパフォーマンスとメモリ使用量を改善します(不要なローカル変数の割り当てを回避することにより)。

シングルトンがどのように悪いかについての私の答えは、常に「正しいことをするのは難しい」です。言語の基本的なコンポーネントの多くは、コンピューティングの他の側面(localhost、デフォルトルート、仮想ファイルシステムなど)のコンポーネントと同様に、シングルトン(クラス、関数、名前空間、さらには演算子)であり、偶然ではありません。それらは時々トラブルやフラストレーションを引き起こしますが、多くのことがうまく機能するようにすることもできます。

私が目にする2つの最大のねじ込みは、グローバルな&のように扱うことです。シングルトンクロージャの定義に失敗しました。

シングルトンは基本的にそうだからです。ただし、グローバルの多くの(残念ながらすべてではない)悪は、本質的にグローバルであることに起因するのではなく、それをどのように使用するかに起因します。シングルトンについても同様です。実際には、「単一インスタンス」などです。本当に「グローバルにアクセス可能」を意味する必要はありません。それはより自然な副産物であり、私たちがそれから来ることがわかっているすべての悪いことを考えると、私たちはグローバルなアクセシビリティを悪用するためにそんなに急いでいるべきではありません。プログラマがシングルトンを見ると、そのインスタンスメソッドを介して常に直接アクセスするように見えます。代わりに、他のオブジェクトと同じようにナビゲートする必要があります。ほとんどのコードは、Singletonを処理していることに気づいてさえいないはずです(疎結合ですよね?)。グローバルのようにほんの少しのコードだけがオブジェクトにアクセスする場合、多くの害は取り消されます。インスタンス関数へのアクセスを制限して強制することをお勧めします。

シングルトンコンテキストも非常に重要です。シングルトンの特徴は、「1つのみ」ということですが、真実は「1つだけ」です。ある種のコンテキスト/名前空間内。通常は、スレッド、プロセス、IPアドレス、またはクラスターごとに1つですが、プロセッサー、マシン、言語名前空間/クラスローダー/何でも、サブネット、インターネットなどごとに1つにすることもできます。

もう1つの、あまり一般的ではない間違いは、シングルトンライフスタイルを無視することです。 1つしかないからといって、シングルトンが全能であることを意味するわけではありません。最も絶望的な状況でのみ。

これらの間違いを避ければ、シングルトンは依然としてPITAになりえますが、最悪の問題の多くが大幅に軽減されるのを見る準備ができています。 Javaシングルトンを想像してください。これは、クラスローダーごとに明示的に定義され(スレッドセーフポリシーが必要)、定義された作成および破棄メソッドと、いつ、どのように呼び出されるか、およびその「インスタンス」メソッドにはパッケージ保護があるため、通常は他の非グローバルオブジェクトを介してアクセスされます。依然として潜在的なトラブルの原因ですが、確かにはるかに少ないトラブルです。

悲しいことに、シングルトンのやり方の良い例を教えるのではなく。私たちは悪い例を教え、プログラマーにしばらくそれらを使って逃げさせてから、彼らに悪いデザインパターンであることを伝えます。

Wikipedia Singleton_patternを参照

  

また、一部の人々はアンチパターンと見なされており、過度に使用されていると感じ、クラスの唯一のインスタンスが実際に必要とされない状況で不必要な制限をもたらします。[1] [2] [3] [ 4]

参照(記事の関連する参照のみ)

  1. ^アレックスミラー。 嫌いなパターン#1:シングルトン、2007年7月
  2. ^ Scott Densmore。 シングルトンが悪である理由、2004年5月
  3. ^ Steve Yegge。 シングルトンは愚かと見なされます、2004年9月
  4. ^ J.B. Rainsberger、IBM。 シングルトンを賢く使用する、2001年7月

シングルトン自体が悪いというわけではありませんが、GoFのデザインパターンは悪いです。実際に有効な唯一の引数は、特にテストが並行して実行される場合、GoF設計パターンはテストに関しては役に立たないということです。

コードで次の手段を適用する限り、クラスの単一インスタンスを使用することは有効な構成です。

  1. シングルトンとして使用されるクラスがインターフェースを実装していることを確認してください。これにより、同じインターフェースを使用してスタブまたはモックを実装できます

  2. シングルトンがスレッドセーフであることを確認してください。それは当然です。

  3. シングルトンは本質的に単純であり、過度に複雑であってはなりません。

  4. 特定のオブジェクトにシングルトンを渡す必要があるアプリケーションのランタイム中に、そのオブジェクトを構築するクラスファクトリを使用し、クラスファクトリがシングルトンインスタンスをそれを必要とするクラスに渡すようにします。

  5. テスト中および確定的な動作を確認するために、実際のクラス自体またはその動作を実装するスタブ/モックとして個別のインスタンスとしてシングルトンクラスを作成し、それを必要とするクラスにそのまま渡します。テスト中にシングルトンを必要とするテスト中のオブジェクトを作成するクラスファクターは、単一のグローバルインスタンスを渡すため、使用しないでください。これは目的に反します。

並列テスト実行ストリームで決定論的な動作を保証するテスト可能な大成功を収めたソリューションでシングルトンを使用しました。

Vince Huston には次の基準があり、私にとっては合理的だと思われます。

  

シングルトンは、次の3つの基準がすべて満たされている場合にのみ考慮する必要があります。

     
      
  • 単一インスタンスの所有権を合理的に割り当てることはできません
  •   
  • 遅延初期化が望ましい
  •   
  • グローバルアクセスは他の方法では提供されません
  •   
     

単一インスタンスの所有権、初期化が行われるタイミングと方法、およびグローバルアクセスが問題にならない場合、シングルトンは十分に興味深いものではありません。

受け入れられた答えの4つのポイントに対処したいと思います。うまくいけば、誰かが私が間違っている理由を説明できるようになります。

  1. コードの依存関係を隠すのが悪いのはなぜですか?すでに多数の隠れた依存関係(Cランタイム呼び出し、OS API呼び出し、グローバル関数呼び出し)があり、シングルトンの依存関係を簡単に見つけることができます(instance()を検索)。

    "グローバルに何かを渡さないようにすることはコードのにおいです。"なぜシングルトンをコードの匂いにしないために何かを渡さないのですか?

    シングルトンを回避するためだけに、コールスタック内の10個の関数を介してオブジェクトを渡す場合、それはとても素晴らしいですか?

  2. 単一責任の原則:これは少しあいまいで、責任の定義に依存すると思います。関連する質問は、なぜこの特定"責任"を追加するのでしょうか?クラスの問題ですか?

  3. オブジェクトをクラスに渡すと、そのオブジェクトをクラス内からシングルトンとして使用するよりも密に結合されるのはなぜですか?

  4. なぜ状態が持続する時間を変更するのですか?シングルトンは手動で作成または破棄できるため、コントロールは引き続き存在し、非シングルトンオブジェクトのライフタイムと同じライフタイムを作成できます。

単体テストについて:

  • すべてのクラスがユニットである必要はありません テスト済み
  • ユニットである必要があるすべてのクラスではない テストする必要がある変更する シングルトンの実装
  • ユニットをテストする必要がある 場合、 実装を変更する必要があります クラスを簡単に変更できます シングルトンを使用して 依存関係を介して渡されたシングルトン 注入。

善/悪の議論についてはコメントしませんが、がやってきた。 依存性注入を使用すると、シングルトン、サービスロケーター、および工場の要件がほとんどなくなりました。少なくとも私が行う仕事の種類(JavaベースのWebアプリケーション)にとって、これははるかに生産的でクリーンな環境であることがわかります。

真に単一であるモデルのある側面に使用されていると仮定すると、パターンに本質的に問題はありません。

バックラッシュはその乱用によるものであると考えていますが、これは、理解し、実装するのが最も簡単なパターンであるという事実によるものです。

シングルトンは純粋主義の観点からは悪いです。

実用的な観点から見ると、シングルトンは開発時間と複雑さのトレードオフです

アプリケーションがそれほど変わらないことがわかっている場合は、どちらでも構いません。要件が予期しない方法で変更された場合は、リファクタリングする必要があるかもしれないことを知っておいてください(ほとんどの場合、これで問題ありません)。

シングルトンは単体テストを複雑にすることもあります。

シングルトンはパターンであり、他のツールと同様に使用または悪用できます。

シングルトンの悪い部分は一般的にユーザーです(または、シングルトンが意図されていないことに対して不適切に使用されていると言えます)。最大の犯罪者は、偽のグローバル変数としてシングルトンを使用しています。

シングルトン、たとえばロガーまたはデータベース接続を使用してコードを記述した後、複数のログまたは複数のデータベースが必要であることがわかった場合、問題が発生します。

シングルトンを使用すると、シングルトンから通常のオブジェクトに移動するのが非常に難しくなります。

また、スレッドセーフでないシングルトンを書くのは簡単すぎます。

シングルトンを使用するのではなく、必要なすべてのユーティリティオブジェクトを関数から関数に渡す必要があります。次のように、それらをすべてヘルパーオブジェクトにラップすると簡単になります。

void some_class::some_function(parameters, service_provider& srv)
{
    srv.get<error_logger>().log("Hi there!");
    this->another_function(some_other_parameters, srv);
}

シングルトンの問題はスコープの拡大の問題であるため、カップリングです。単一のインスタンスにアクセスする必要がある状況がいくつかあることを否定するものではなく、他の方法でも実現できます。

制御の反転(IoC)コンテナーを中心に設計し、コンテナによって制御されるライフタイム。これにより、インスタンスに依存するクラスが、単一のインスタンスが存在するという事実に気付かないという利点が得られます。シングルトンの寿命は将来変更される可能性があります。最近出会ったそのような例は、シングルスレッドからマルチスレッドへの簡単な調整でした。

FWIW、それを単体テストしようとするときにPIAである場合、デバッグ、バグ修正、または強化しようとすると、PIAになります。

コメントなしのコーディングのChris Reathによるこのテーマに関する最近の記事。

注:コメントなしのコーディングは無効になりました。ただし、リンクされている記事は別のユーザーによって複製されています。

http://geekswithblogs.net/AngelEyes/archive/2013/09/08/singleton-i-love-you-but-youre-bringing-me-down-re-uploaded.aspx

ここでは、まだ誰も言っていないシングルトンについてもう1つ説明します。

ほとんどの場合、「単一性」インターフェースの特性ではなく、クラスの実装の詳細です。コントロールコンテナの反転は、この特性をクラスユーザーから隠す場合があります。クラスをシングルトンとしてマークする必要があります(たとえば、Javaの @Singleton アノテーションを使用)。それだけです。 IoCCが残りを行います。アクセスは既にIoCCによって管理されているため、シングルトンインスタンスへのグローバルアクセスを提供する必要はありません。したがって、IoCシングルトンに問題はありません。

IoCシングルトンとは反対のGoFシングルトンは、「シングルトン」を公開することになっています。インターフェースでgetInstance()メソッドを使用して、上記のすべての問題に対処します。

シングルトンは悪くありません。グローバルに一意でない何かをグローバルに一意にするのは悪いことです。

ただし、「アプリケーションスコープサービス」があります。 (コンポーネントを相互作用させるメッセージングシステムについて考えてみてください)-シングルトンの「CALLS」、「MessageQueue」 -メソッド&quot; SendMessage(...)&quot;を持つクラス。

その後、あらゆる場所から次の操作を実行できます。

MessageQueue.Current.SendMessage(new MailArrivedMessage(...));

そしてもちろん、次のことを行います:

MessageQueue.Current.RegisterReceiver(this);

IMessageReceiverを実装するクラス内。

スレッドセーフではないオブジェクトをシングルトンパターンで配置する人が多すぎます。 DataContextの例を見てきました( LINQ&nbsp; to&nbsp; SQL )DataContextはスレッドセーフではなく、純粋に作業単位オブジェクトであるという事実にもかかわらず、シングルトンパターンで実行されます。

これらは基本的にオブジェクト指向のグローバル変数であるため、通常はクラスが不要になるようにクラスを設計できます。

複数の人(またはチーム)が類似または同一のソリューションに到達すると、パターンが現れます。多くの人は、元の形式でシングルトンを使用するか、ファクトリーテンプレートを使用します(AlexandrescuのModern C ++ Designでの適切な議論)。オブジェクトの存続期間を管理する際の並行性と難しさが主な障害であり、前者は提案されているように簡単に管理できます。

すべての選択肢と同様に、Singletonには上昇と下降がかなりあります。特に、アプリケーションの寿命を生き延びたオブジェクトに対しては、適度に使用できると思います。彼らがグローバルに似ている(そしておそらくそうである)という事実は、おそらく純粋主義者を引き離した。

まず、クラスとその協力者は、信奉者に焦点を合わせるのではなく、まず意図した目的を実行する必要があります。ライフサイクル管理(範囲外になった場合にインスタンスが破損した場合)は、クラッドの責任の一部であってはなりません。このために受け入れられているベストプラクティスは、依存性注入を使用して依存関係を管理する新しいコンポーネントを作成または構成することです。

ソフトウェアはより複雑になることが多く、「シングルトン」の複数の独立したインスタンスを持つことが理にかなっています。異なる状態のクラス。そのような場合、シングルトンを単純に取得するためにコードをコミットすることは間違っています。 Singleton.getInstance()を使用しても、小さなシンプルなシステムでは問題ないかもしれませんが、同じクラスの別のインスタンスが必要な場合は機能しません/スケールしません。

クラスはシングルトンと見なされるべきではありませんが、それはその使用法または依存関係を構成するためにどのように使用されるかを示すものでなければなりません。迅速で厄介な場合、これは重要ではありません-ファイルパスは重要ではないと言うハードコーディングは控えめですが、より大きなアプリケーションでは、DIを使用してより適切な方法でそのような依存関係を除外および管理する必要があります。

テストでシングルトンが引き起こす問題は、ハードコーディングされた単一の使用事例/環境の症状です。テストスイートと多くのテストはそれぞれ個別であり、シングルトンのハードコーディングと互換性のないものを分離します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top