11

重複の可能性:
デザインパターンについて:シングルトンをいつ使用するのですか?

この質問は、シングルトンが一般的に「有害と見なされる」かどうかに関するものではありません。あなたの経験から、シングルトンがうまく機能しているように見える特定の状況を知りたいだけです。

編集:シングルトンの適切性および/または悪性について一般的 に議論したい場合は、既存の質問があります: 13797511831

おっとっと!私の質問がすでにここで尋ねられていることを発見しました:デザインパターンについて:シングルトンをいつ使用するのですか?

4

12 に答える 12

8

基本的に、ロギングと構成の 2 つの目的で使用します。どちらも、アプリに中央構成と中央ログファイルがあることを前提としており、常に有効であるとは限りませんが、ほとんどのコードでは有効です。また、重要なメタデータが重複していないことを確認したい特定のファクトリ クラスまたはキャッシュ クラスに対して、それらを使用することもあります。

于 2010-01-17T12:55:24.383 に答える
5

コメントを展開しています...

質問の言葉遣いが不十分です。シングルトンは多くの状況でうまく機能するようです。「シングルトンが負の特性を公開しない特定の状況は何ですか?」簡単に言えば、「グローバル変数が良いのはいつですか」?

  1. グローバル変数はグローバル変数です。

    使ったらすぐ

    void f() { X* x = X::getInstance(); ... }

    ではなくvoid f(X*)、スパゲティ料理のご注文を承りました。

  2. シングルトンは増殖し、相互に依存することを好みます。 SessionManagerを使用EventManagerしますLogManager。誰かがログ ファイルに現在のユーザーの名前を記載することを望んでいます。LogManagerメンテナは を追加し、も を使用する がログイン失敗をログに記録するSessionManager::getInstance()->getUser()->getName();まで、すべてのバラを追加します。LoginManagerLogManager

  3. シングルトンはテスト容易性を阻害します。

    単一インスタンス プロパティは、運用コードでのみある程度役立ちます。関数をまったくテストできない可能性がありvoid f()、おそらくハッピー パスに対してのみ (少数の) テストを行うことになります。

ご想像のとおり、グローバル変数が適切な場合に対する私の答えは? 「決して」です。あなたのものは何ですか?

于 2010-01-17T14:29:30.187 に答える
2

乱数のシーケンスの生成 - 乱数ジェネレーターは一意である必要があり、使用ごとにインスタンス化されません。これをスレッドレベルのシングルトンとして実装したい場合があります。ただし、この場合でもプロセス全体のシングルトンが適切です。

于 2010-01-17T16:41:52.640 に答える
2
  • ドメインが、モデル化しているものの一意のインスタンスが 1 つだけ存在することを指定している場合

シングルトンは避けるべきだと今でも信じています(少なくともJavaでは)。

考慮すべき点が 2 つあります。Singleton パターンを適用するための概念メカニズムです。

シングルトンの概念には多くの用途、ロギング、構成があり、作業しているドメインに実際にそれらのインスタンスが 1 つしかないものがあり、それをモデル化したい場合は言うまでもありません。つまり、会社には単一の経費処理オフィスしかなく、経費フォームを無効なオフィスに送信するのは間違っています。オフィスは実際にはシングルトンです。シングルトンの概念には、多くの正当な用途があります。

ただし、通常、問題を引き起こすのはメカニズムです。Java では、constructor を宣言することによってオブジェクトを構築できないように強制しますprivate。これに関する問題は、具象クラスを介してインスタンスへのグローバルなアクセス ポイントも提供する必要があることです。これにより、アプリケーション内のすべてが具体的なクラスに結合されます。これは、実行時に変更したり、単体テストでモックしたりすることはできません。特にテスト容易性の観点から、悪と見なされるのはこのメカニズムです。

シングルトンの概念を貧弱なメカニズムから切り離すことができれば、それほど悪くはありません。@Singleton1 つの例として、 Guice で使用できるスコープが考えられます。Guice のコンテキストでは、1 つのインスタンスが保証されますが、悪意のあるプライベート コンストラクター/グローバル ポイント オブ アクセス メカニズムではこれを実現できません。

于 2010-01-17T16:16:07.523 に答える
1
  • ロギング。

  • ローカライズされた文字列リソースの検索Strings.get("CONFIRM_DELETE")

これらは両方とも、オブジェクトのパブリック インターフェイスで公開する必要がある詳細ではないため、ここでシングルトンを使用することは理にかなっています。

于 2010-01-17T13:25:45.463 に答える
1

システムには単一のデバイス/ハードウェアが接続されており、それを適切に使用するには中央の制御ポイントが必要です。

于 2010-01-17T10:15:23.673 に答える
0

マスター サーバーはクライアントからの要求を受け取り、これらの要求を下位プロセスに渡します。従属プロセスは、マスターサーバーとの通信にシングルトンを使用する場合があります。

于 2010-01-17T13:10:22.737 に答える
0

私は Singleton に依存しないようにしていますが、Singleton を使用しないよりもデカップリングを好みます。したがって、私はシングルトンを Prototype パターンと組み合わせてよく使用します。これにより、ライブラリの読み込み時にプロトタイプを登録できます (グローバル オブジェクトの構築)。

多数のライブラリで構成されるサーバーを作成しています。多数の「共通」ライブラリがあり、サービスごとに 1 つのライブラリがあります。「メイン」ライブラリには、受信したメッセージを確認し、キーに応じて適切なサービスを呼び出すという目的があります...これは単純なstd::map.

マップにシングルトンを使用すると、コードを完全に分離できます。サービス ライブラリに依存するライブラリはなく、サービス ライブラリの外部にあるコード行は、そのサービスの登録を担当しません。実際、コンパイル時に「リンク」コマンドを変更するだけで、どのサービスを埋め込むかを決定できます。ライブラリとリンクしないと、そのサービスは埋め込まれません。

そこでは本当に便利だと思います...構成などのために、MonoPatternを使用することを好みます。つまり、すべてのインスタンスが同じデータを共有する(したがって、実際のシングルトンをラップする)通常の外観のクラスです。クライアントはシングルトンのアンダーカバーを使用していることを知らないため、必要な場合に備えて移行を容易にします。

于 2010-01-17T13:11:30.347 に答える
0

私が取り組んでいる現在のプロジェクトで、シングルトンを取り除くために本当に一生懸命働きました。臭いがありますが、避けるのが非常に難しい場合があります。

私の状況では、セキュリティ、構成などの管理機能を処理するためのシングルトン オブジェクトを構築する API がありました。API は EntityFramework を使用し、プラグインも (MEF を使用して) プルしました。これらのクラスの構築は常にコードによって実行されるとは限らなかったため (特に EF エンティティの場合)、これらをビジネス オブジェクトにエレガントに挿入することが常に可能であるとは限りませんでした。そこで私はシングルトンを使用しました。シングルトンは、後継者の範囲内でプロジェクト内のどこからでもアクセスできます。

于 2010-01-17T10:17:31.480 に答える
0

ロギングに加えて (他のほとんどの人が既に述べているように)、制御の反転 (IoC) コンテナーにシングルトンを使用しました。依存関係は、アプリケーションの開始時に 1 回登録され、シングルトン メソッドを使用して、アプリ中の任意の時点で依存関係を解決できます。

于 2010-01-17T13:34:30.497 に答える
-1

プログラムの一部で特定のインターフェイスを実装するオブジェクトが必要な場合 (ポリモーフィズムに関して)、そのオブジェクトの複数のインスタンスは必要ありません。それ以外の場合は、静的メソッドで十分です。

于 2010-01-17T12:58:37.777 に答える
-1

ユニークなリソースと見なしたいアイテムに適しています。

Web システムの例として、提供されるページごとに 1 つのデータベース接続のみを使用したい場合があります。この場合、シングルトン パターンを使用するのが理にかなっています。(ただし、データベース アクセス オブジェクトがシングルトンであることを認識してコーディングする必要がありますが、これはあまり理想的ではありませんが、明確に文書化されている場合などは許容されます。)

于 2010-01-17T10:18:30.010 に答える