1798

シングルトンパターンの完全に支払われたメンバーですGoFパターンブックしかし、最近では開発者の世界によってかなり孤立しているようです。私はまだ特にたくさんのシングルトンを使います。ファクトリークラスそして、あなたがマルチスレッドの問題(実際には他のクラスのように)について少し注意を払わなければならない間、私はそれらがそれほどひどい理由を見ていません。

Stack Overflowは、特にシングルトンが悪であることに誰もが同意すると仮定しているようです。どうして?

「あなたの答えを支持してください。」事実、参照、または特定の専門知識


  • 私はコードを適応させようとしたので、シングルトンデザインを使うことが最近私をやけどさせたと言わなければなりません。空き時間にやっているので、これをリファクタリングするのは怠惰すぎます。生産性にとって悪い知らせ - Marcin
  • たくさんの'があります'回答にはありますが、パターンが良い場合の良い例をいくつかご覧ください。悪い例とは対照的です。 - DGM
  • 私は数か月前にこの問題についてブログ記事を書いた。jalf.dk/blog/2010/03/… - そしてそれを完全に言っておきましょう。私は個人的にシングルトンが正しい解決策である単一の状況を考えることはできません。それはそのような状況が存在しないことを意味するわけではありません、しかし...まれにそれらを呼ぶことは控えめな表現です。 - jalf
  • @AdamSmithという意味ではありません持ってるに、しかしそれはあなたを意味しますできるそのようにアクセスしてください。そのようにアクセスするつもりがないのであれば、そもそもそれをシングルトンにする理由はほとんどありません。ですから、あなたの主張は事実上「シングルトンを作っても害はありません」。扱うシングルトンとしてそれ。ええ素晴らしいです。車を運転しないと、私の車も汚染されません。でも、そもそも車を買わないほうが簡単です。 ;)(完全な開示:実際に車は持っていません) - jalf
  • このトピック全体の最悪の部分は、シングルトンを嫌う人々が代わりに何を使うべきかについて具体的な提案をすることはめったにないということです。たとえば、このSO記事全体を通してのジャーナル記事や自己発行ブログへのリンクは、なぜ続けてではないシングルトンを使用すること(そしてそれらはすべての優れた理由による)が、代替品に関しては非常にスリムです。しかし、たくさんの手を振っています。シングルトンを使用しない理由を新しいプログラマに教えようとしている人たちの多くは、疑わしい例を挙げただけで、優れたサードパーティの反例を指摘していません。それは疲れています。 - Ti Strga

30 답변


1182

Brian Buttonからの言い換え:

  1. それらは一般的にグローバルなインスタンスとして使用されています、なぜそれはそれほど悪いのでしょうか?なぜなら、インターフェースを通してそれらを公開するのではなく、あなたのコードの中であなたのアプリケーションの依存関係を隠すからです。それを回避しないようにグローバルなものを作ることはコード臭

  2. 彼らは単一責任原則:彼らが彼ら自身の創造とライフサイクルをコントロールするという事実のおかげで。

  3. それらは本質的にコードを厳しくします結合した。これは、多くの場合、テスト中にそれらを取り出すのをかなり難しくします。

  4. それらはアプリケーションの存続期間中は状態を伝えます。テストを注文する必要があるという状況に陥る可能性があるため、テストに再度ヒットすることになります。これは、単体テストには大きな問題です。どうして?なぜなら、各単体テストは互いに独立しているべきだからです。


  • 私はあなたに同意しません。コメントは600文字しか許可されていないので、私はこれについてコメントするためにBlog Postを書きました。下のリンクを見てください。jorudolph.wordpress.com/2009/11/22/singleton-considerations - Johannes Rudolph
  • ポイント1と4では、シングルトンは便利で、実際には(特にDBからの)データのキャッシュにはほぼ完璧だと思います。パフォーマンスの向上は、単体テストのモデリングに伴う複雑さをはるかに超えています。 - Dai Bok
  • @Dai Bok:"データのキャッシュ(特にDBからの")これを行うにはプロキシパターンを使用します。 - paxos1977
  • うわー、素晴らしい回答。私はおそらくここでは過度に攻撃的な表現を使ったので、否定的な質問に答えていたことを覚えておいてください。私の答えは、アンチパターンの簡単なリストです。それは悪いシングルトンの使用法から発生します。完全な開示私もシングルトンを使うことがあります。シングルトンが良い考えであると考えることができるときのために優れたフォーラムを作るであろうSOに関してより中立的に提起された質問があります。例えば、stackoverflow.com/questions/228164/… - Jim Burger
  • マルチスレッド環境でのキャッシュにはあまり適していません。限られたリソースをめぐって複数のスレッドが競合していると、キャッシュを簡単に無効にできます。 [シングルトンによって管理されています] - monksy

414

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

リソースの競合

いくつかのリソースがあれば

1)単一のインスタンスしか持てません。

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

あなたには必要だシングルトン

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

シングルトンが必要になることは稀です。彼らが悪いのは、彼らがグローバルそして彼らは、GoFの全額支払われたメンバーです。デザインパターン本。

あなたがグローバルを必要としていると思うとき、あなたは恐ろしいデザインミスをしているでしょう。


  • ハードウェアもその一例です。組み込みシステムには、シングルトンを使用するハードウェアが多数あります。 < grin> - Jeff
  • 完全に同意する。 「このやり方は悪い」という決定的なことがたくさんあります。練習がその場所を持っているかもしれないという認識なしで浮遊して話す。多くの場合、練習は「悪い」だけです。それは頻繁に悪用されているからです。シングルトンパターンが適切に適用されている限り、それは本質的に何の問題もありません。 - Damovisa
  • 本物の原則的なシングルトンは非常にまれです(そしてプリンタキューは確かに1つではなく、どちらもログファイルではありません - log4jを参照)。多くの場合、ハードウェアは、原則ではなく偶然の一致によるシングルトンです。 PCに接続されているすべてのハードウェアはせいぜい偶然のシングルトンです(複数のモニタ、マウス、プリンタ、サウンドカードを考えてください)。 500万ドルの粒子検出器でさえ、偶然の一致と予算の制約からシングルトンです - ソフトウェアには適用されないので、シングルトンはありません。電気通信では、電話番号も物理電話もシングルトンではありません(ISDN、コールセンターと考えてください)。 - digitalarbeiter
  • ハードウェアにはさまざまなリソースのインスタンスが1つしかない場合がありますが、ハードウェアはソフトウェアではありません。開発ボード上の単一のシリアルポートをシングルトンとしてモデル化する必要があるという理由はありません。実際、そのようにモデル化すると、2つのポートを持つ新しいボードへの移植が難しくなります。 - dash-tom-bang
  • 2つのポートを表す2つのシングルトンを持つことができるように、たくさんのコードを複製した2つの同一クラスを作成しますか。 2つのグローバルSerialPortオブジェクトを使うだけではどうでしょうか。ハードウェアをまったくクラスとしてモデル化しないのはどうですか。また、なぜシングルトンを使用するのですか。これはグローバルアクセスも意味します。欲しいですかすべてのシリアルポートにアクセスできるようにあなたのコードで機能しますか? - jalf

315

一部のコーディングスノブはそれらを単なる賛美されたグローバルとして見下しています。多くの人が嫌いなのと同じようにgoto声明を使用するという考えを憎む他の人がいるグローバル。私は何人かの開発者がこれを避けるために驚くべき長さになるのを見ました。グローバル彼らは失敗を認めるものとしてそれを使うことを考えたからです。奇妙だが本当だ。

実際にはシングルトンpatternは単なるプログラミング技法であり、概念のツールキットの一部です。時々あなたはそれが理想的な解決策であると思うかもしれないのでそれを使う。しかし、それを使うためにはデザインパターンそれがちょうどそれであるのでこれまでにそれを使用することを拒否するのと同じくらい愚かですグローバル


  • シングルトンで私が見た失敗は、彼らがどういうわけか「より良い」ので、人々がグローバルの代わりにそれらを使うということです。問題は(私が見ているように)、これらの場合にSingletonがテーブルにもたらすものは無関係だということです。 (たとえば、実際にコンストラクタを使用していない場合でも、最初に使用するコンストラクトは、シングルトン以外で実装するのは簡単です。) - dash-tom-bang
  • その理由は「私たち」です。見下ろしているのは、「私たち」です。非常に頻繁にそれらが間違って使われているのを見て、そしてあまりにも頻繁に"私たち"彼らには彼らの原因の場所があることを知っていますか。 - Bjarke Freund-Hansen
  • @Phil、あなたは「時々、それが理想的な解決策だと思うかもしれないので、それを使う」と述べました。わかりましたどっちシングルトンが便利だと思うでしょうか。 - Pacerier
  • @Pacerier、次の条件がすべて当てはまる場合はいつでも、(1)何か必要なものが1つだけある、(2)多数のメソッド呼び出しの中でその1つを引数として渡す必要がある、(3)いたるところにあちこちのものを渡さないことによって、コードのサイズと複雑さを即座に減らす代わりに、いつかリファクタリングする必要がある可能性があります。 - antinome
  • 私はこれが何かに答えているとは思わない、それはただ時々それが合うかもしれない、そして時々それが合わないかもしれないということを言っているだけである。でも、なぜ、そしていつ?この答えを単なる以上のものにしているのは、モデレートへの引数? - Guildenstern

205

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

シングルトンは病的嘘つきですシングルトンが依存関係の連鎖を把握し、アプリケーションを起動またはテストすることを困難にする可能性があることを示すユニットテストの例があります。それは虐待のかなり極端な例ですが、彼がしていることはまだ有効です。

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

すべてのシングルトンがなくなったところ依存性注入によって、それらを必要とするコンストラクタへのインスタンスの取得が容易になったという点は、最初の記事で説明された悪いグローバルなシングルトンの背後にある根本的なニーズを軽減します。


  • この件に関するMiskoの記事は、現時点では最もよく取り上げられている記事です。 - Chris Mayer
  • 最初のリンクでは、実際にはシングルトンの問題に対処していませんが、クラス内の静的な依存関係を想定していません。指定された例では、パラメータを渡して修正することができますが、それでもシングルトンを使用することは可能です。 - DGM
  • @DGM:そのとおりです。実際、理論的根拠の間には大きな論理的な断絶があります。記事の一部であり、'シングルトンが原因です。'部。 - Harper Shelby
  • MiskoのCreditCardの記事は極端なこのパターンの誤用の例 - Alex
  • 2番目の記事のシングルトンは、実際には説明したオブジェクトモデルの一部です。しかし、グローバルにアクセスできるのではなく、これらはFactoryオブジェクトに対してプライベートです。 - FruitBreak

106

私は混乱が人々がシングルトンパターンの本当の応用を知らないという事実によって引き起こされると思います。私はこれを十分に強調することはできません。シングルトンはではないグローバルをラップするパターンシングルトンパターンはそれを保証するためにのみ使われるべきです与えられたクラスのただ一つのインスタンス実行時に存在します。

彼らはグローバルにそれを使用しているので人々はシングルトンは悪だと思います。シングルトンが見下ろされているのは、この混乱のためです。シングルトンとグローバルを混同しないでください。それが意図されていた目的のために使用されるならば、あなたはシングルトンパターンから極端な利益を得るでしょう。


  • アプリ全体で利用可能な、その1つのインスタンスは何ですか?ああ。グローバル。 "シングルトンはではないグローバルをラップするパターン"素朴か誤解を招く定義により、パターンはグローバルインスタンスの周りにクラスをラップします。 - cHao
  • もちろん、アプリケーションの起動時にクラスのインスタンスを1つ自由に作成し、そのインスタンスをインターフェイスを介してそれを使用するものに注入することができます。実装は1つしかないことを気にする必要はありません。 - Scott Whitlock
  • @Dainius:実際には、そうではありません。もちろん、インスタンスを他のインスタンスに任意に置き換えることはできません。 (これらの顔面惹起の瞬間を除いてあなたがやる。実際に見たことがあるsetInstanceしかし、それはほとんど問題ではありません。シングルトンもカプセル化についてのおかしいことや、変更可能なグローバル状態の何が悪いのかを知らなかったので、彼はすべての人にセッターを提供しました。シングル。フィールド。 (そして、はい、これは起こります。ロット。私がこれまでに見たことがあるほとんどすべてのシングルトンは、設計によって変更可能であり、しばしば恥ずかしいことにそうでした。) - cHao
  • @ダイニウス:大部分は、すでに持っています。 "継承よりも構成を優先"今はかなり前からあることです。継承するときです明らかに最善の解決策、しかし、あなたはもちろんそれを使用して自由です。シングルトン、グローバル、スレッディング、と同じことgotoなど作業多くの場合、率直に言って"動作"十分ではありません - 慣習的な知恵に反したい場合は、自分のアプローチがどのように行われているかを示すことができたほうがよいでしょう。より良い従来のソリューションよりも。シングルトンパターンについては、まだそのようなケースは見ていません。 - cHao
  • 私たちがお互いを超えて話すのではなく、私は単に世界的に利用可能なインスタンスについて話しているのではありません。そのためにたくさんの事件があります。私が話しているのは(特に「capital-S Singleton」と言うとき)、その単一のグローバルインスタンスをクラス自体に埋め込む、GoFのSingletonパターンです。getInstanceまたは同様の名前の付いたメソッドで、2番目のインスタンスの存在を防ぎます。率直に言って、その時点で、あなたも同様に持っていないかもしれません1インスタンス。 - cHao

70

シングルトンに関するもう1つの悪い点は、それらを簡単に拡張できないことです。あなたは基本的に何らかの種類で構築する必要がありますデコレータパターンあなたが彼らの振る舞いを変えたいなら、あるいはそのようなこと。また、ある日、その1つのことを複数の方法で実行したい場合は、コードのレイアウト方法によっては、変更するのがかなり面倒な場合があります。

注意すべき1つのことは、シングルトンを使用する場合は、直接アクセスするのではなく、必要な人に渡してみることです。それ以外の場合は、シングルトンで行うことを複数の方法で行うことにします。シングルトンに直接アクセスする場合、各クラスが依存関係を埋め込むので、変更がかなり困難です。

だから基本的に:

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

のではなく:

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

このようなパターンは、依存性注入そして一般的には良いことだと考えられています。

他のパターンと同じように...それについて考えて、与えられた状況でのその使用が不適切であるかどうかを検討してください...規則は通常破られるように作られていますパターン何も考えずに何もしないで適用しないでください。


  • ああ、あなたがこれをいたるところでやるとしたら、あちこちにsingeltonへの参照を回さなければならないでしょう、そしてそれ故あなたはもうシングルトンを持っていないでしょう。 :)(これは通常良いことですIMOです。) - Bjarke Freund-Hansen
  • @ BjarkeFreund-Hansen - ナンセンス、君は何について話しているの?シングルトンは、一度インスタンス化されるクラスのインスタンスです。このようなシングルトンを参照しても、実際のオブジェクトはコピーされず、参照されます - 同じオブジェクトが得られます(シングルトンと同じ)。 - M. Mimpen
  • @ M.Mimpen:いいえ、大文字のSシングルトン(ここで説明しているもの)は、次のようなクラスのインスタンスです(a)保証する1つのインスタンスしか存在しないこと、および(b)クラス独自の組み込みグローバルアクセスポイントを介してアクセスされること。何も呼ぶべきでないとあなたが宣言したならばgetInstance()そして、(b)はもはや真実ではありません。 - cHao
  • 私はあなたをフォローしていないか、私がコメントしている人に理解できていません - それはBjarke Freund-Hansenに対するものです。 Bjarkeは、シングルトンの参照が複数あると、シングルトンが複数あると述べています。ディープコピーがないので、それは確かに真実ではありません。 - M. Mimpen
  • @ M.Mimpen:私は彼のコメントを意味の影響についてもっと言及するために取ります。あなたがへの呼び出しを違法にしたらgetInstance()シングルトンパターンと通常の参照との間の1つの有用な違いを効果的に排除しました。コードの他の部分に関しては、単一性はもはや特性ではありません。の発信者のみgetInstance()これまでにいくつのインスタンスが存在するかを知っているか、気にする必要さえあります。呼び出し元が1人だけの場合は、呼び出し元に単純に参照を格納してそれを再利用させるよりも、クラスが確実に単一性を適用するための労力と柔軟性が高くなります。 - cHao

65

シングルトンパターンはそれ自体問題ではありません。問題は、オブジェクト指向のツールを使ってソフトウェアを開発している人々がオブジェクト指向の概念をしっかり理解していなくても、そのパターンがよく使われることです。この文脈でシングルトンが導入されると、それらは少しの使用のためにヘルパーメソッドを含む管理できないクラスに成長する傾向があります。

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

ごみ収集環境シングルトンはすぐにメモリ管理に関して問題になる可能性があります。

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


  • 私はそれが何年も前のスレッドであることを知っています。こんにちは@Kimoz uは言った: - シングルトンはすぐにメモリ管理に関して問題になることができます。シングルトンにどのような問題が発生する可能性があるのか、より詳細に説明したいと思います。ガベージコレクション - Thomas
  • @ Kimoz、質問は尋ねています"シングルトンパターン自体はなぜ問題ではないのですか。そして、あなたは単にポイントを繰り返しましたが、シングルトンパターンの単一の有効なユースケースさえ提供しませんでした。 - Pacerier
  • @Thomas、定義上、シングルトンは1つのインスタンスにのみ存在するためです。そのため、唯一の参照をnullに割り当てるのは複雑なことがよくあります。それは可能ですが、それ以降はシングルトンがアプリケーションで使用されなくなるまでの時点を完全に制御することになります。そしてこれはまれであり、通常、シングルトン愛好家が探しているものとは正反対です。単一のインスタンスを作成する簡単な方法です。常にアクセス可能GuiceやDaggerのようないくつかのDIフレームワークでは、シングルトンを取り除くことは不可能であり、それはメモリに永遠にとどまります。 (コンテナ提供のシングルトンは自家製のものよりはるかに優れていますが)。 - Snicolas

52

シングルトンは静的メソッドを使って実装されます。静的メソッドは、単調なテストをする人々によって避けられないのです。このサイトのほとんどの人はユニットテストを強く支持しています。それらを避けるための一般的に最も受け入れられている規約は制御の逆転パターン。


  • これは、オブジェクト(ユニット)、関数(ユニット)、ライブラリ全体(ユニット)をテストできるユニットテストの問題のように思えますが、クラス(ユニットも)の静的なものでは失敗します。 - v010dya
  • あなたはとにかくすべての外部参照をモックするとは思わないのですか?もしあなたがそうであれば、そうでなければ、あなたは本当に単体テストをやっているのですか? - Dainius
  • @ダイニウス:モッキングインスタンスクラスをあざけるよりもはるかに少ないトラブルです。あなたはおそらくアプリケーションの残りの部分からテスト中のクラスを抽出し、偽でテストすることができますSingletonクラス。しかし、それはテストプロセスを非常に複雑にします。一つには、今、あなたは自由にクラスをアンロードすることができる必要があります(ほとんどの言語で実際にはオプションではありません)、またはテストごとに新しいVMを起動します(read:テストは何千倍もかかるかもしれません)。 2人の場合は、しかし、への依存Singletonテスト全体に漏れている実装の詳細です。 - cHao
  • Powermockは静的なものをモックすることができます。 - Snicolas
  • オブジェクトをあざけることは、実際のオブジェクトを作成することを意味しますか?モックで実際のオブジェクトが作成されない場合、クラスがシングルトンなのかメソッドが静的なのかが重要なのはなぜでしょうか。 - Arun Raaj

42

それがなるとシングルトンも悪いですクラスタリング。それで、あなたはもうあなたのアプリケーションに "厳密に一つのシングルトン"を持っていません。

次のような状況を考えてください。開発者として、データベースにアクセスする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。あなたの生産環境は今このようになります:Single Singleton

これまでのところすべて問題ありません。

では、Webアプリケーションの複数のインスタンスを1つのクラスタに設定したいとします。さて、あなたは突然次のようなものがあります。

Many singletons

それは奇妙に聞こえますが、今すぐあなたのアプリケーションに多くのシングルトンがあります。そしてそれはまさにシングルトンがあるべきではないということです:それの多くのオブジェクトを持つこと。この例に示すように、データベースに対して同期呼び出しを行いたい場合、これは特に悪いことです。

もちろん、これはシングルトンの悪い使い方の一例です。しかし、この例のメッセージは次のとおりです。アプリケーションにシングルトンのインスタンスが1つだけ存在するとは限りません。特にクラスタ化の場合はそうです。


  • シングルトンの実装方法がわからない場合は、そうしないでください。自分が何をしているのかわからない場合は、最初にそれを見つけ、その後に初めて必要なことを行うようにしてください。 - Dainius
  • これは面白いです、質問があります。では、シングルトン(それぞれが異なるマシン/ JVM上にある)が単一のデータベースに接続している場合、正確には何が問題になりますか?シングルトンのスコープはその特定のJVM専用であり、クラスタ内でも同じです。私たちの意図はアプリケーションを超えた単一のオブジェクトであったため、この特定の状況は悪いと哲学的に言うのではなく、私はこの配置のために発生する可能性のある技術的問題を見て幸せです。 - Saurabh Patil

34

  1. グローバル変数として簡単に(ab)使用されます。
  2. シングルトンに依存するクラスは単独で単体テストするのが比較的困難です。


30

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

読んだあとシングルトンは病的嘘つきですで示唆されているようにジェイソンの答え私はこの小さなちょっとした一口を見つけました。どうやってシングルトンはしばしば誤用されます。

グローバルは悪いです:

  • a。名前空間の競合が発生します
  • b。それは不当な方法で国家を公開します

シングルトンになると

  • a。それらを呼び出す明示的なオブジェクト指向の方法は、衝突を防ぎます。問題ではない
  • b。状態のないシングルトンは(工場のように)問題にはなりません。状態を持つシングルトンは、ふたつのカテゴリに分類できます。不変であるか、一度書いてたくさん読む(config / propertyファイル)です。これらは悪くありません。リファレンスホルダーの一種である可変シングルトンは、あなたが話しているものです。

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

これはモノポリーにどのように当てはまりますか?

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

  • 最初にルールを設定して、誰もが同じページにいるようにします。
  • ゲーム開始時に全員が平等にスタートする
  • 混乱を避けるために提示されているルールは1セットのみです。
  • ルールはゲーム中に変更することはできません

今、そうではない人のために本当に独占を果たした、これらの標準はせいぜい理想的です。独占はお金に関係しているので、独占の敗北は飲み込むのが難しいです。負けた場合、残りのプレイヤーがゲームを終えるのを注意深く見守る必要があります。そのため、通常、他の人を犠牲にして一部のプレーヤーの自己利益に応えるために、ある時点でルールがねじれます。

だから、あなたは友達のボブ、ジョー、そしてエドと独占しています。あなたは迅速にあなたの帝国を築き、指数関数的な割合で市場占有率を消費しています。あなたの対戦相手は弱っていて、あなたは(比喩的に)血をかぎ始めます。あなたの相棒Bobは彼のお金の全てを可能な限り多くの低価値の物件をグリッドロックするのに投入しました、しかし彼は彼が期待したように高い投資収益率を得ていません。ボブは不運の一撃としてあなたのボードウォークに着地し、ゲームから切り出されます。

今度はゲームは友好的なダイスロールから重大なビジネスに行きます。ボブは失敗の例にされました、そして、ジョーとエドは「あの男」のように終わることを望みません。ですから、あなたが主役になって、突然あなたは敵になるでしょう。 JoeとEdは、テーブルの下での取引、背後でのお金の投入、過小評価されたハウススワッピング、そして一般的に、プレーヤーの1人がトップに上がるまであなたを弱めるための何かを練習し始めます。

それから、それらのうちの1つが勝つ代わりに、プロセスは最初から始まります。突然、有限の一連のルールが動く標的となり、ゲームはSurvivor以降のすべての高評価のリアリティTV番組の基盤を構成する社会的相互作用のタイプに退化します。なぜ、ルールが変更されているのか、そしてそれらがどのように/なぜ/何を表すべきかについてコンセンサスがないからです。さらに重要なことに、決定を下す人は誰もいません。その時点で、ゲーム内のすべてのプレイヤーは自分のルールを作成しており、2人のプレイヤーが疲れきってしゃべりに追いついてゆっくりとあきらめることができなくなります。

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

これはプログラミングにどのように当てはまりますか。

可変のシングルトンが存在する明白なスレッド安全性と同期の問題の他に... 1セットのデータがある場合、それは複数の異なるソースによって同時に読み取り/操作される可能性があり、アプリケーションの実行期間中に存在します。 「ここでは適切な種類のデータ構造を使用していますか」と尋ねて尋ねるのは、おそらくいい機会です。

個人的には、プログラマがシングルトンをアプリケーション内のある種のねじれクロススレッドデータベースストアとして使用することによってシングルトンを悪用するのを見たことがあります。コードを直接処理したところ、(スレッドセーフにするために必要なすべてのスレッドロックのために)遅いことと(同期バグの予測不可能/断続的な性質のために)悪夢のためであったことを証明できます。 「製造」条件下でテストすることはほぼ不可能です。確かに、パフォーマンスの問題のいくつかを克服するためにポーリング/シグナリングを使用してシステムを開発した可能性がありますが、それでテストの問題は解決しません。 /スケーラブルな方法。

シングルトンはのみシングルトンが提供するものが必要な場合のオプション。オブジェクトの書き込み専用の読み取り専用インスタンス。その同じ規則は、オブジェクトのプロパティ/メンバにもカスケードするはずです。


  • シングルトンがデータをキャッシュするとどうなりますか? - Yola
  • @Yolaシングルトンが事前に決められたおよび/または固定されたスケジュールで更新されるようにスケジュールされていると、書き込み数が削減され、それによってスレッドの競合が減少します。それでも、同じ使い方をシミュレートする非シングルトンインスタンスを偽造しない限り、シングルトンと対話するコードを正確にテストすることはできません。 TDDの人々はおそらくフィットするでしょうが、それはうまくいくでしょう。 - Evan Plaice
  • @EvanPlaice:モックがあっても、次のようなコードでいくつか問題があります。Singleton.getInstance()。リフレクションをサポートする言語は、One True Instanceが格納されているフィールドを設定することでそれを回避できるかもしれません。ただし、IMOでは、別のクラスの非公開国で詐欺に遭遇すると、テストの信頼性が少し低下します。 - cHao

21

シングルトンはシングルインスタンスではありません!

他の答えとは異なり、私はシングルトンの何が悪いのかについて話すのではなく、それらが正しく使われたときにどれほど強力で素晴らしいかをあなたに見せたいのです!

  • 問題:シングルトンはマルチスレッド環境では難題となり得る

    溶液処置:シングルスレッドのブートストラップ・プロセスを使用して、シングルトンのすべての依存関係を初期化してください。
  • 問題:シングルトンをモックするのは難しいです。

    溶液:利用方法工場あざけるためのパターン

    MyModel myModel = Factory.inject(MyModel.class); あなたはマッピングすることができますMyModelTestMyModelいつでもどこでもそれを継承するクラスMyModelあなたが得るだろう注入されますTestMyModel読みました。
  • 問題:シングルトンは決して破棄されないのでメモリリークを引き起こす可能性があります。

    溶液:まあ、それらを処分する!シングルトンを適切に配置するためにあなたのアプリにコールバックを実装し、あなたはそれらにリンクされたデータを削除し、最後に:それらをFactoryから削除するべきです。

私がタイトルシングルトンで述べたように単一インスタンスについてではありません。

  • シングルトンは読みやすさを向上させる:クラスを見て、それがどのようなシングルトンをインジェクトしたのかを見ることで、それがどのような依存関係にあるのかを知ることができます。
  • シングルトンはメンテナンスを改善する:クラスから依存関係を削除した後は、シングルトンインジェクションを削除しただけで、依存関係を移動させた他のクラスへの大きなリンクを編集する必要はありません。@Jim Burger
  • シングルトンはメモリとパフォーマンスを向上させる:アプリケーションで何らかの問題が発生し、それが配信されるまでに長いコールバックチェーンが必要になった場合は、Singletonを使用することで中間者を削減し、(不要なローカル変数を回避して)パフォーマンスとメモリ使用量を改善できます。割り当て)。


  • これは、シングルトンに関する私の主な問題ではありません。シングルトンは、プロジェクト内の何千ものクラスのいずれかからグローバル状態へのアクセスを許可します。 - LegendLength
  • それが目的でしょう… - Ilya Gazman

21

ウィキペディアを見るSingleton_pattern

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

参考文献(記事からの関連する参考文献のみ)

  1. ^アレックスミラー。私が嫌いなパターン#1:シングルトン2007年7月
  2. ^スコットDensmore。なぜシングルトンは悪なのか2004年5月
  3. ^スティーブYegge。愚かと見なされるシングルトン2004年9月
  4. ^ J.B. Rainsberger、IBM。シングルトンを賢く使う2001年7月


  • パターンについての説明では、なぜそれが悪と見なされているのか説明されていません... - Jrgns
  • あまり公平ではありません。「あまり使用されていないと感じる人もいますが、クラスの唯一のインスタンスが実際には必要ない場合には不要な制限が導入されるため、アンチパターンとも見なされます。」参考文献を見てください...とにかく私にはRTFMがあります。 - GUI Junkie

20

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

私が見ている2つの最大の失敗は、次のとおりです。シングルトンクロージャを定義できませんでした。

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

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

もう1つの、それほど一般的ではない間違いは、Singletonのライフスタイルを無視することです。 1つしかないからといって、シングルトンが「常にあった、そしてこれからも」全能であることを意味するわけでも、一般的に望ましいことでもありません(開始および終了のないオブジェクトはコード内のあらゆる種類の有用な仮定に違反し、採用されるべきです)最も絶望的な状況の中で。

これらの間違いを避けても、Singletonsは依然としてPITAになる可能性があります。最悪の問題の多くが大幅に軽減されるのを見る準備ができています。 Javaシングルトンを想像してみてください。これは、クラスローダーごとに1回明示的に定義され(スレッドセーフティポリシーが必要です)、定義および作成メソッドとそれらが呼び出されるタイミングと方法を決定するライフサイクルを持ちます。パッケージ保護なので、通常は他の非グローバルオブジェクトを介してアクセスされます。まだ潜在的な問題の原因ですが、確かにはるかに少ない問題です。

悲しいことに、シングルトンのやり方の良い例を教えるよりはむしろ。私たちは悪い例を教え、プログラマがしばらくそれらを使わないようにし、そしてそれらが悪いデザインパターンであることを伝えます。


16

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

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

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

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

  3. シングルトンは本質的に単純で、過度に複雑ではないはずです。

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

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

私たちのソリューションではシングルトンを使用してきましたが、それは並列テストランストリームにおける決定論的な振る舞いを保証するテストが可能です。


  • +1、最後にその答えはいつシングルトンは有効かもしれません。 - Pacerier

15

ヴィンスハストンこれらの基準を持っていて、それは私には妥当と思われます

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

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

単一インスタンスの所有権、いつ、どのように初期化が行われるのか、およびグローバルアクセスが問題にならないのであれば、Singletonはあまり面白くありません。


14

私は受け入れられた答えの中の4つの点に対処したいのですが、うまくいけば誰かが私が間違っている理由を説明することができます。

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

    「回避しないようにグローバルなものを作るのはコードの匂いです。」なぜシングルトンをコードの臭いにするのを避けるために何かを渡していないのですか?

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

  2. 単一責任の原則:これは少しあいまいであり、責任の定義によります。関連する質問は、なぜこれを追加するのでしょうか特定階級問題に対する「責任」?

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

  4. それはなぜ国家が存続する期間を変えるのですか?シングルトンは手動で作成または破棄することができます。そのため、コントロールはまだ存在しており、有効期間を非シングルトンオブジェクトの有効期間と同じにすることができます。

単体テストについて

  • すべてのクラスが単位である必要はない テスト済み
  • 単位である必要があるすべてのクラスではありません テストする必要がある シングルトンの実装
  • もし彼らが行うユニットテストする必要があります 実装を変更する必要がありますか からクラスを変更するのは簡単です シングルトンを使って 依存関係を介して渡されたシングルトン 注入。


  • 1.これらすべての隠れた依存関係それらも悪いです。隠された依存関係は常に悪です。しかし、CRTとOSの場合、彼らは既にそこにいます、そして、彼らは何かを成し遂げる唯一の方法です。 (ランタイムやOSを使用せずにCプログラムを書いてみてください。)そのことを行う能力は、そのマイナス面を大きく上回っています。私たちのコードの中のシングルトンはそれほど豪華ではありません。それらは私たちの管理と責任の範囲内でしっかりと守られているので、あらゆる使い方(読むことで隠された依存関係を読むこと)はすべて物事を成し遂げる唯一の合理的な方法として正当化できるはずです。非常に、非常にそれらのいくつかは実際にあります。 - cHao
  • 2.「責任」通常、「変更の理由」として定義されています。シングルトンはその寿命を管理することとその本当の仕事をすることの両方を終えます。仕事のやり方を変えるならまたはオブジェクトグラフの作成方法は、クラスを変更する必要があります。しかし、他のコードがオブジェクトグラフを作成していて、あなたのクラスが実際の仕事をしているのであれば、その初期化コードでオブジェクトグラフを設定することができます。テストダブルを挿入してすべてを自由に分解できるため、隠れた可動部品に頼る必要がなくなります。 - cHao
  • 「モノをやる能力が彼らのネガティブを大きく上回っている」ことをあなたが認識しているのは良いことです。例はロギングフレームワークでしょう。開発者がロギングをしないことを意味している場合、関数呼び出しのレイヤを介して依存性注入によってグローバルロギングオブジェクトを渡すことを強制することは厄介です。したがって、シングルトン。 3.クラスのクライアントにポリモーフィズムを介して振る舞いを制御させたい場合にのみ、密結合ポイントが関係します。多くの場合そうではありません。 - Jon
  • 4.「手動で破棄できない」ことがわかりません。 「は1つのインスタンスのみになる」という論理的な意味です。それがあなたがシングルトンを定義する方法であるならば、それで我々は同じことについて話していません。全クラスいけない単体テストする。これはビジネス上の決定であり、市場投入までの時間や開発コストが優先されることもあります。 - Jon
  • 3.多態性が必要ない場合は、インスタンスも必要ありません。それを静的クラスにしても、とにかく単一のオブジェクトと単一の実装に縛られることになるかもしれません - そして少なくともAPIがそれほど嘘をついているわけではありません。 - cHao

13

私は善悪の議論についてコメントするつもりはありませんが、私はそれ以来使用していません。一緒に来た。を使う依存性注入シングルトン、servicelocatorsと工場のための私の要件をほとんど取り除きました。少なくとも私が行う作業の種類(JavaベースのWebアプリケーション)では、これははるかに生産的でクリーンな環境になります。


  • 春の豆、デフォルトでは、シングルトン? - slim
  • ええ、でも私は'コーディング'シングルトン。シングルトンを作成していません。 (つまり、デザインパターンに従って、プライベートコンストラクタやだややややと) - しかしそう、春には、私は単一のインスタンスを使用しています。 - prule
  • それで、他の人がそうするとき、それは大丈夫です(私が後でそれを使うならば)、しかし、他の人がそれをし、私がそれを使わないなら、それは悪ですか? - Dainius

12

シングルトンは純粋主義者の観点からは良くありません。

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

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

シングルトンも時々複雑になる単体テスト


  • 私の経験はそれです起動シングルトンを使用すると、長期的にはカウントされず、短期的にも本当にあなたを傷つけるでしょう。この効果は、アプリケーションがしばらくの間既に存在していて、おそらく他のシングルトンに既に感染している場合には、それほどでもないかもしれません。ゼロから始めますか?絶対に避けてください。オブジェクトの単一のインスタンスが欲しいですか?このオブジェクトのインスタンス化をファクトリに管理させます。 - Sven
  • AFAIKシングルトンですファクトリーメソッドしたがって、私はあなたの推薦を得ません。 - tacone
  • "工場" !="同じクラス内の他の便利なものから分離できないfactory_method" - Sven

11

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

私は、反動がその過剰利用のせいであると信じています。それは、理解し、実行するのが最も簡単なパターンであるという事実によるものです。


  • この反発は、正式な単体テストを実践している人々に関係していると思います。 - Jim Burger
  • なぜこれが-1なのかわからない。それは最も説明的な答えではありませんが、彼もまた間違っていません。 - Outlaw Programmer

11

シングルトンはパターンであり、他のツールと同じように使用または悪用される可能性があります。

シングルトンの悪い部分は、一般的にはユーザーです(または、それがするように設計されていないことに対するシングルトンの不適切な使用を言うべきです)。最大の違反者は偽のグローバル変数としてシングルトンを使用しています。


  • ありがとうLoki :)その通りです。全体の魔女狩りは私に後藤の議論を思い出させます。ツールは使い方を知っている人のためのものです。気に入らないツールを使用すると危険な場合があるので避けてください。ただし、使用しないように/正しく使用する方法を習得しないように他の人に指示しないでください。私は正確には「プロシングルトン」ではありません。しかし、私はそのような道具があるという事実が好きで、それを使うのが適切な場所を感じることができます。期間。 - dkellner

8

ロガーやデータベース接続など、シングルトンを使用してコードを作成したときに、複数のログまたは複数のデータベースが必要であることがわかった場合は、問題があります。

シングルトンはそれらから普通のオブジェクトへ移動することを非常に困難にします。

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

シングルトンを使用するのではなく、必要なすべてのユーティリティオブジェクトを機能ごとに渡す必要があります。このように、それらすべてをヘルパーオブジェクトにラップすれば、単純化することができます。

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


  • すべてのメソッドの引数を渡すことは素晴らしいです、それはあなたのAPIを汚染する方法少なくとも10の方法に行くべきです。 - Dainius
  • これは明らかな欠点であり、ネストされた呼び出しに何らかの形で伝播する引数によって言語によって処理されるべきだったものですが、そのようなサポートがない場合は手動で行う必要があります。システムクロックを表すオブジェクトのように、自然なシングルトンでさえトラブルの可能性があると考えてください。たとえば、クロック依存のコード(複数の電気料金メーターを考える)をテストでどのようにカバーするのでしょうか。 - Roman Odaisky
  • シングルトンをテストしていないのであれば、テスト方法によって異なります。2つのリモートオブジェクトがお互いの動作に依存していれば、シングルトンの問題ではありません。 - Dainius
  • どの言語でネストされた呼び出しに伝播するのでしょうか。 - Dainius
  • あるモジュールが他のモジュールに依存していて、それを理解できない、または理解できない場合、シングルトンであるかどうかにかかわらず、難しいことはありません。コンポジションを使うべき場所で継承を使うことがよくありますが、継承が悪いとは言わないで、OOPは絶対に避けなければなりません。多くの人がそこでデザインミスをしているのでしょうか。 - Dainius

7

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

私は今の周りに設計することを好む制御の逆転(IoC)コンテナを使用して、コンテナによってライフタイムを制御できるようにします。これにより、単一のインスタンスが存在するという事実に気付かないように、インスタンスに依存するクラスの利点が得られます。シングルトンの寿命は将来変更することができます。私が最近遭遇したそのような例は、シングルスレッドからマルチスレッドへの簡単な調整でした。

あなたがそれを単体テストしようとするときそれがPIAならばそれはあなたがそれをデバッグしようとするとき、それはPIAに行くつもりです、バグ修正または強化。


7

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

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

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


6

これはまだ誰も言っていないシングルトンに関するもう一つのことです。

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

IoCシングルトンとは反対側のGoFシングルトンは、getInstance()メソッドを介してインタフェース内の "シングルトン性"を公開することになっているため、上記のすべての問題を抱えています。


  • 私の意見では、 "singletonity"はこれは実行時環境の詳細であり、クラスコードを書いたプログラマによって考慮されるべきではありません。そうではなく、クラスUSERによって行われることを考慮しています。 USERだけが実際に必要なインスタンス数を知っています。 - Earth Engine

6

シングルトンは悪くありません。グローバルにユニークではなく、グローバルにユニークなものを作るときにだけ悪いのです。

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

その後、いたるところから次のことができます。

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

そしてもちろん、

MessageQueue.Current.RegisterReceiver(this);

IMessageReceiverを実装するクラス内


  • そして、もっと小さなスコープで2番目のメッセージキューを作成したいのなら、それを作成するためにあなたのコードを再利用できないのはなぜですか?シングルトンはそれを防ぎます。ただし、通常のメッセージキュークラスを作成した後に、「アプリケーションスコープ」として機能する1つのグローバルインスタンスを作成しただけの場合は、一つは、私は他の用途のために2番目のインスタンスを作成することができます。しかし、あなたがそのクラスをシングルトンにするならば、私は書く必要があります二番目メッセージキュークラス。 - jalf
  • また、MessageQueueのような場所から適切に呼び出すことができるように、グローバルなCustomerOrderListだけを用意しないでください。答えはどちらの場合も同じだと思います。グローバル変数を効果的に作成しているのです。 - LegendLength

6

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


  • 安全でないマルチスレッドコードを書く人が多いのですが、それはスレッドを排除する必要があるということですか? - Dainius
  • @ダイニウス:実はそうです。 IMOのデフォルトの並行性モデルは、(1)メッセージを互いに簡単にやり取りする、および/または(2)必要に応じてメモリを共有するという方法で、マルチプロセスにする必要があります。あなたが共有したい場合はスレッドが便利ですすべてのものしかし、あなたは本当にそれを望んでいません。アドレス空間全体を共有することによってエミュレートすることもできますが、これもアンチパターンと見なされます。 - cHao
  • @Dainius:そしてもちろん、それは正直さと善意の同時性がまったく必要だと想定していることです。 OSが他のことをするのを待つ間に、あなたが望むことは1つのことができることだけです。 (ソケットからの読み取り中にUIを更新するなど)まともな非同期APIは、ほとんどの場合、フルオンスレッドを不要にする可能性があります。 - cHao
  • 大量のデータがあり、処理が必要な場合は、1つのスレッドで処理することをお勧めします。多くの人にとって、これは間違っている可能性があるためです。 - Dainius
  • @ダイニウス:多くの場合、そうです。 (スレッド化は実際にはあなたを遅くするあなたがミックスに同期を追加するならば。これは、マルチスレッドがほとんどの人にとって最初の考えではない理由の主な例です。他の場合では、必要なものだけを共有する2つのプロセスがある方が良いでしょう。もちろん、プロセスがメモリを共有するように調整する必要があります。率直に言って、私はそれを良い物事 - 少なくともすべて共有モードにデフォルト設定するよりもはるかに優れています。どの部分が共有されているのか、つまりどの部分がスレッドセーフである必要があるのかを明示的に(そして理想的には知るために)言う必要があります。 - cHao

4

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


  • クラスが1回限りのインスタンスに制限されていない場合は、クラス内に静的メンバーが必要です。これは、ほぼ同じことが言えます。あなたが提案した代替案は何ですか? - Jeach
  • < MainScreen>で巨大なアプリケーションを持っています。この画面は多くの小さなモーダル/非モーダルウィンドウ/ UIフォームを開きます。私は、MainScreenはシングルトンであるべきだと思います。たとえば、アプリケーションのはるか隅にあるウィジェットがMainScreenのステータスバーにそのステータスを表示したい場合は、MainScreen.getInstance( .setStatus(" Some Text");代替案として何を提案しますか?アプリケーション全体にMainScreenを渡しますか? :D - Salvin Francis
  • @SalvinFrancis:私がお勧めするのは、自分が気にしないことや、アプリをこっそりとこっそり遊んではいけないことを気にするようなオブジェクトを用意するのをやめることです。 :)あなたの例はイベントを使ったほうがずっといいでしょう。イベントを正しく実行すると、ウィジェットはメインスクリーンがあるかどうかを気にする必要すらありません。それはただ「ちょっと、ものが起こった」と放送します、そしてなんでも「起こったこと」を購読しています。イベント(MainScreen、WidgetTest、またはその他の完全なものなど)によって、応答方法が決まります。それがOOPのしくみです想定されたとにかくするために。 :) - cHao
  • @Salvinデバッグ時にMainScreenについて静かに推論することがいかに難しいかを検討してください。多くのコンポーネントによって更新されました。あなたの例は、シングルトンが悪い理由の完璧な理由です。 - LegendLength

4

複数の人(またはチーム)が類似または同一の解決策にたどり着くと、パターンが出現します。多くの人がまだシングルトンをオリジナルの形で使ったりファクトリテンプレートを使ったりしています(AlexandrescuのModern C ++ Designでよく議論されています)。オブジェクトの存続期間を管理する際の並行性と困難さが主な障害です。

すべての選択肢と同様に、シングルトンは浮き沈みの公正なシェアを持っています。私はそれらが適度に、特にアプリケーションの寿命を生き残ったオブジェクトのために使用できると思います。彼らが世界的に似ている(そしておそらくそうである)という事実は、おそらく純粋主義者を後押ししている。


4

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

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

どのクラスもシングルトンと考えるべきではありませんが、むしろそれはその使用法や扶養家族の設定にどのように使用されるかの応用であるべきです。厄介なことにはこれは問題ではありません。ファイルパスは問題にならないと言うだけでなく、DIを使用してより適切な方法でそのような依存関係を管理する必要があります。

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

リンクされた質問


関連する質問

最近の質問