シングルトンは熱く議論されているデザイン パターンであるため、スタック オーバーフロー コミュニティがシングルトンについてどう考えているかに興味があります。
「シングルトンは怠惰なプログラマー向けだ!」だけでなく、意見の理由を教えてください。
シングルトンの使用に反対していますが、この問題に関するかなり良い記事があります: Scientificninja.com: performant-singletons。
他に良い記事を持っている人はいますか?多分シングルトンをサポートしていますか?
シングルトンは熱く議論されているデザイン パターンであるため、スタック オーバーフロー コミュニティがシングルトンについてどう考えているかに興味があります。
「シングルトンは怠惰なプログラマー向けだ!」だけでなく、意見の理由を教えてください。
シングルトンの使用に反対していますが、この問題に関するかなり良い記事があります: Scientificninja.com: performant-singletons。
他に良い記事を持っている人はいますか?多分シングルトンをサポートしていますか?
シングルトンを守るために:
シングルトンに対して:
私自身の意見:
私はシングルトンを使用していますが、合理的な代替手段がある場合は使用しないでください。これまでのところ、これはうまく機能しており、テストする作業が少し増えますが、テスト可能であることがわかりました。
Google には、Java 用のSingleton Detectorがあります。これは、Google で作成されたすべてのコードで実行する必要があるツールとして始まったと思います。シングルトンを削除する簡単な理由:
テストが困難になり、設計の問題が隠される可能性があるためです。
より明確な説明については、Google の「 Why Singletons Are Controversial 」を参照してください。
シングルトンは、仮装したグローバル変数の集まりです。
グローバル変数には、シングルトンと同様に用途がありますが、厄介なグローバル変数を使用する代わりに、シングルトンでクールで便利なことをしていると思うなら (グローバル変数が悪いことは誰もが知っています)、残念ながら誤解されています。
シングルトンの目的は、クラスがインスタンスを 1 つだけ持つようにし、そのインスタンスへのグローバルなアクセス ポイントを提供することです。ほとんどの場合、焦点は単一のインスタンス ポイントにあります。それがGlobaltonと呼ばれたとしたら想像してみてください。これは、(通常は) グローバル変数の否定的な意味合いを強調するため、あまり魅力的ではないように思えます。
シングルトンに対する良い議論のほとんどは、シングルトンのテストダブルを作成するのは簡単ではないため、テストで提示される困難に関係しています。
Google Testing ブログには、Miško Heveryによるシングルトンに関する 3 つの非常に優れたブログ投稿があります。
シングルトンは、よく誤用されていますが、恐ろしいパターンではありません。この誤用は、それがより簡単なパターンの 1 つであり、シングルトンに慣れていないほとんどの人がグローバルな副作用に惹かれているためだと思います。
Erich Gammaは、シングルトンは GOF ブックに含まれないことを望んでいるパターンであり、設計が悪いと述べていました。私は反対する傾向があります。
任意の時点でオブジェクトの単一インスタンスを作成するためにパターンが使用されている場合、そのパターンは正しく使用されています。グローバルな効果を与えるためにシングルトンが使用されている場合、それは正しく使用されていません。
短所:
利点:
私はめったにシングルトンを使用しないため、ひよこは私を掘り下げます。いいえ、真剣に、私はシングルトン パターンが大好きです。あなたが理由を知っている?なぜなら:
確かに、「専門家」は「単体テスト」と「依存性注入」についてたくさんの話を投げかけますが、それはすべてディンゴの腎臓の負荷です. シングルトンは単体テストが難しいと思いますか? 問題ない!すべてを公開宣言するだけで、クラスをグローバルな良さの楽しい家に変えることができます。1990 年代のハイランダーという番組を覚えていますか? シングルトンは、次のような理由でそのようなものです。 A. 死ぬことはありません。および B. 存在できるのは 1 つだけです。したがって、これらすべての DI ウィニーに耳を傾けるのをやめ、放棄してシングルトンを実装してください。ここにいくつかの正当な理由があります...
シングルトンパターンの使用については大きな誤解があると思います。ここでのコメントのほとんどは、グローバルデータにアクセスする場所としてそれを参照しています。ここで注意する必要があります-パターンとしてのシングルトンはグローバルにアクセスするためのものではありません。
シングルトンは、指定されたクラスのインスタンスを1つだけ持つために使用する必要があります。パターンリポジトリには、シングルトンに関する優れた情報があります。
私が一緒に働いた同僚の 1 人は、非常にシングルトン志向でした。マネージャーや上司のようなオブジェクトがあるときはいつでも、彼はそれをシングルトンにしました。そして、システムがいくつかの新しい要件を取り上げるたびに、複数のインスタンスを許可する完全に正当な理由があることが判明しました。
ドメインモデルが(「提案」ではなく)シングルトンがあることを指示する場合は、シングルトンを使用する必要があると思います。他のすべてのケースは、偶然にもクラスの単一インスタンスです。
聖戦!わかりました。見てみましょう。前回デザインをチェックしたとき、警察が言った。
シングルトンは自動テストを妨げるため、問題があります。テストケースごとにインスタンスを新たに作成することはできません。代わりに、ロジックは、簡単にインスタンス化してテストできるクラス(A)に含める必要があります。別のクラス(B)は、作成の制約を担当する必要があります。単一責任の原則を前面に!AにアクセスするためにBを経由することになっていることをチームが知っている必要があります-一種のチームコンベンションです。
私はほとんど同意します。
ここでかわいそうなシンゲルトンを救う方法を考えてみましたが、難しいことは認めざるを得ません。それらの正当な使用法はほとんど見たことがなく、依存性注入と単体テストを実行する現在のドライブでは、それらを使用するのは非常に困難です。それらは間違いなく、デザインパターンを使ったプログラミングの「カーゴカルト」の現れです。私は、「GoF」の本を読んだことはないが、「シンゲルトン」を知っているため、「パターン」を知っている多くのプログラマーと仕事をしてきました。
私はオリオンに反対しなければなりませんが、ほとんどの場合、ドレスのグローバル変数ではなく、ドレスのグローバルサービス(メソッド)のように、シンゲルトンが乱用されているのを見てきました。CLR インターフェイスを介してセーフ モードで SQL Server 2005 で Singeltons を使用しようとすると、システムがコードにフラグを立てることに注意してください。問題は、実行される可能性のある特定のトランザクションを超えて永続的なデータがあることです。もちろん、インスタンス変数を読み取り専用にすると、問題を回避できます。
その問題は、私にとって1年間多くのやり直しにつながりました。
シングルトンの最大の問題は、特にテストを並行して独立して実行したい場合に、単体テストが困難になることです。
2 つ目は、ダブルチェック ロックを使用した遅延初期化が実装に適していると人々がよく信じていることです。
最後に、シングルトンが不変でない限り、アプリケーションをスケールアップして複数のプロセッサで複数のスレッドで実行しようとすると、簡単にパフォーマンスの問題になる可能性があります。競合同期は、ほとんどの環境でコストがかかります。
会社に関するデータを保存/取得するための永続化レイヤーとの通信、従業員や価格コレクションの処理など、数十の責任があったため、仮装した単なる変数の集まりではありませんでした。
単一のオブジェクトであるべきものを実際に説明しているわけではなく、データのシリアライゼーションを除いて、それらのいずれかがシングルトンであるべきだったことは議論の余地があります。
私が通常設計するクラスのセットを少なくとも 3 つ見ることができますが、限られた一連のタスクを非常にうまく実行する、より小さく単純なオブジェクトを好む傾向があります。これはほとんどのプログラマーの性質ではないことを私は知っています。(はい、私は毎日 5000 行クラスの怪物に取り組んでおり、一部の人々が作成する 1200 行のメソッドが特に好きです。)
ポイントは、ほとんどの場合、シングルトンは必要なく、多くの場合、あなたの人生を難しくしているだけだということだと思います.
私はSpringと組み合わせてシングルトンを何度も使用しましたが、松葉杖や怠惰とは考えていませんでした。
このパターンで可能になったのは、一連の構成タイプの値に対して単一のクラスを作成し、その特定の構成インスタンスの単一の(変更不可能な)インスタンスをWebアプリケーションの複数のユーザー間で共有することでした。
私の場合、シングルトンには、そのクライアントに固有のクライアント構成基準(cssファイルの場所、db接続基準、機能セットなど)が含まれていました。これらのクラスは、Springを介してインスタンス化およびアクセスされ、同じ構成のユーザー(つまり、同じ会社の2人のユーザー)によって共有されました。* **このタイプのアプリケーションの名前があることは知っていますが、それは私を逃れています*
アプリのユーザーごとに、これらの「定数」オブジェクトの新しいインスタンスを作成(次にガベージコレクション)するのは無駄だったと思います。
シングルトンには用途がありますが、それらの使用と公開には注意が必要です。これは、悪用が容易であり、真の単体テストが困難であり、相互にアクセスする 2 つのシングルトンに基づいて循環依存関係を簡単に作成できるためです。
ただし、すべてのデータが複数のインスタンス間で同期されていることを確認したい場合に役立ちます。たとえば、分散アプリケーションの構成は、シングルトンに依存して、すべての接続が同じ最新のものを使用するようにする場合があります。データの日付セット。
シングルトンを使用することに決めた理由について、非常に注意する必要があることがわかりました。他の人が述べたように、それは本質的にグローバル変数を使用するのと同じ問題です。あなたは非常に用心深く、それを使って何ができるかを考えなければなりません。
それらを使用することは非常にまれであり、通常はより良い方法があります。シングルトンで何かを行った後、コードをふるいにかけ、それがどれほど悪いことかを発見した後 (または、はるかに優れた、より健全な解決策を思いついた後) に遭遇しました。 )
たとえばJavaのシングルトンで恐ろしいことの1つは、場合によっては同じシングルトンの複数のインスタンスになる可能性があることです。JVMは、クラスの完全修飾名と、そのロードを担当するクラスローダーの2 つの要素に基づいて一意に識別します。
つまり、互いに認識しない 2 つのクラスローダによって同じクラスがロードされる可能性があり、アプリケーションのさまざまな部分が、対話するこのシングルトンのさまざまなインスタンスを持つことになります。
私は、仮装のアイデアにおける一連のグローバル変数については、まったく同意しません。シングルトンは、適切な問題を解決するために使用すると非常に便利です。実際の例を挙げましょう。
私は以前、自分が働いていた場所向けに小さなソフトウェアを開発しました。いくつかのフォームでは、会社、従業員、サービス、および価格に関する情報を使用する必要がありました。最初のバージョンでは、システムはフォームが開かれるたびにデータベースからそのデータをロードし続けました。もちろん、私はすぐに、このアプローチが最善の方法ではないことに気付きました。
次に、その場所に関するすべてをカプセル化したcompanyという名前のシングルトン クラスを作成し、システムが開かれるまでにデータで完全に満たされました。
会社に関するデータを保存/取得するための永続化レイヤーとの通信、従業員や価格コレクションの処理など、数十の責任があったため、仮装した単なる変数の集まりではありませんでした。
さらに、会社のデータを保持するための固定された、システム全体の、簡単にアクセスできるポイントでした。
シングルトンは非常に便利であり、それを使用すること自体はアンチパターンではありません。ただし、主に悪い評判を得ているのは、それらとやり取りするために、消費するコードにシングルトンであることを認めるように強制するためです。つまり、それらを「非シングルトン化」する必要がある場合、コードベースへの影響が非常に大きくなる可能性があります。
代わりに、Singleton をファクトリの背後に隠すことをお勧めします。そうすれば、将来サービスのインスタンス化の動作を変更する必要がある場合、Singleton を使用するすべてのタイプではなく、ファクトリを変更するだけで済みます。
さらに良いことに、コントロール コンテナの反転を使用してください。それらのほとんどにより、インスタンス化の動作をクラスの実装から分離できます。
通常の、テスト可能で、注入可能なオブジェクトを作成し、Guice/Spring などにインスタンス化を処理させます。真剣に。
これは、キャッシュの場合でも、シングルトンの自然な使用例が何であれ適用されます。1 つのインスタンスを強制しようとするコードを書くという恐怖を繰り返す必要はありません。依存性注入フレームワークに処理させてください。(軽量 DI コンテナーをまだ使用していない場合は、Guice をお勧めします)。