web-dev-qa-db-ja.com

シングルトンパターン

重複の可能性:
シングルトンはいつ適切ですか?

私は新しいプログラマーで(最初の仕事から4か月)、最近デザインパターンに関心を持っています。最近使ったのはシングルトンです。ただし、 this thread に関するコメントを見てください。悪いフィードバックがあります。なぜ誰かが説明できますか?

私はいくつかの場所でそれが便利であるとわかりましたが、おそらく静的クラスを使用せずに同じことを達成できたでしょう。

26
Darren Young

グローバル変数と同じ問題があります。

変更可能な状態へのグローバルアクセスを提供します。

シングルトンを使用するものはすべて、密に結合されています。

密結合を避けてください。コードの更新が難しくなります。テストが難しい。

選択がシングルトン変数またはグローバル変数の場合。少なくともシングルトンは遅延初期化を提供します。

ただし、通常は、グローバルにアクセス可能な変更可能な状態を避け、すべての依存関係をパラメーターまたはコンストラクターを介してコードに渡すことをお勧めします。これにより、コードが特定のインスタンスから分離されます。

注:定数状態へのグローバルアクセスはそれほど重要ではありません。

これは、Googleエンジニアが行った主題についての良い話です:
http://www.youtube.com/watch?v=-FRm3VPhseI

シングルトンパターンlooksは、実装が最も簡単なパターンの1つです(デザインパターを初めて見たとき)。比較的簡単ですが、その実装にはいくつかの落とし穴があります(すべて言語固有です)。しかし、シングルトンについて学ぶことの最も難しい部分は、それらをいつ使用するかを学ぶことはめったにありません(ほとんどの人は決して主張しないでしょうが、シングルトンを使用できないことを自分自身に納得させるのは難しいと思います(私が数回思ったことは、ほとんどが間違いでした(しかし、学習方法)))。

27
Martin York

単純なグローバル変数に対してシングルトンが役立つのは、グローバルアクセスが必要で、複数のインスタンスを持つerrorの場合だけです。シングルトンを使用してログファイルを表す人もいますが、ログクラスの複数のインスタンスを持つことはerrorではありません(たとえば、特定の目的のために別のファイルにログを記録します。ログクラスがシングルトンの場合、これは不可能です)。

グローバルアクセスを要求するだけの問題ではないことに注意してください。これはグローバルアクセスであり、複数のインスタンスがあるとエラーになります。

通常、グローバルアクセスが必要な場合は、グローバル変数で十分です(人々はグローバル変数を好まないが、シングルトンは確かにグローバル変数の過剰使用の解決策ではありません)。シングルトンやグローバル変数の代わりに アスペクト指向プログラミング を使用することが、より優れたアプローチであることがよくあります。

13
Dean Harding

あなたはこれが役立つかもしれません: https://stackoverflow.com/questions/2765060/stateless-singleton-vs-static-methods/2765251#2765251

要約する:

  • 静的クラスに対する実際のシングルトンの利点は、シングルトンがインターフェースを実装できることです。
  • シングルトンのポイントは、値へのグローバルアクセスを許可することではなく、型のインスタンス化を制御することです。

greetz
back2dos

5
back2dos

そのスレッドを調べることなく、グローバル変数の薄いラッパーとして何度も使用されているのを見てきました。豚に口紅をつけるのと似ています。デザインパターンで包んだからといって、問題が発生するわけではありません。

編集:どうやらなぜグローバルが悪いのか説明する必要がありますか?イントロが必要な場合は、グローバルについて here を読むことができます。

「スクライブは、グローバル変数を置き換えるための見当違いの試みでシングルトンを頻繁に使用します。たとえば、シングルトンが「よく知られたオブジェクト」として記述されているプロジェクトに携わっています-それは私の子、グローバル変数のように聞こえませんか? ?」

「うーん……いや、本当じゃない」ちょっと考えて引いた。ホワイトボードに次のように書いた。

S &S::Instance() 
{   
    static S theInstance;   
    return theInstance; 
}

「ここにはグローバル変数が表示されません。」 「ああ、私の子ですが、グローバル変数-S :: Instance(という名前のグローバル変数があります。このたとえを考えてみましょう。

class T { /* whatever */ }; 
T globalT;

「globalTとtheInstanceの違いは何ですか?どちらの変数にも静的な保存期間がありますか?」

したがって、グローバル変数をマスクすることのみを目的とするシングルトンを作成しないでください。

2
red-dirt

シングルトンで注意しなければならないことの1つは、それらが実際にシングルトンであることを確認することです。たとえば、Javaを使用すると、シングルトンの作成時にいくつかの追加の対策を講じず、それにアクセスしたいスレッドがたくさんある場合、「シングルトン」のインスタンスが多くなる可能性があります。 」.

また、RMIを使用するアプリケーションがあり、クライアントとサーバーに「シングルトン」を作成する場合でも、シングルトンはありますか?

これらは単なるJava=の例ですが、私はいくつかの点を指摘しています。ほとんどの人が引用する問題は、いくつかのオブジェクトがseem本当にしないでくださいは1にする必要があります。たとえば、オブジェクトファクトリのインスタンスを1つ持つのはいいかもしれませんが、強制する必要はありません。明示的に作成することしかできませんが、周りの2つは物事を壊しません。

2
Jeremy Heiler

シングルトンは、本質的に本質的に何か(通常は実世界に存在するもの)を表す場合に意味がありますが、何らかの静的リソースを表す場合にも意味があります。

2
Loren Pechtel

豚に口紅をつける。それはとても興味深いので、新しい答えを作成する必要がありました。

つまり、ロギングに関して...

  • ロギングターゲットごとに個別のシングルトンを作成することはできません。たとえば、logError()-> write、logWarning()-> writeなど(???)
  • シングルトンログ(タイプ)->書き込み(???)を取得するときにログタイプを選択できません
  • 必要に応じて、クラスの別のインスタンスを作成することはできません(「グローバル」ロギングにシングルトンを使用して同じクラスを作成し、特定のインスタンスを作成できます)(???)

では、この場合にシングルトンを使用するよりも優れていると思いますか?

  • 多分すべてのクラスオブジェクトのすべての関数にログクラスインスタンスを渡す
  • おそらく、要求に応じてログクラスを作成するだけで、行の数だけファイルを開いてロックまたは閉じる必要があります(非常に最適です)。
  • 静的クラス...同じ問題。パフォーマンスは最低だ...
  • グローバル機能(素敵な混乱)
  • グローバルオブジェクト(再び素敵な混乱)

シングルトンは、いつでもどこでもグローバルオブジェクトを変更できるか、他の誰かがそれを上書きできるため、優れた設計手法です。シングルトンパターンでは使用できません。

悪いフィードバック?教育を受けていない開発者からですか? :)わかりました。悪用したパターンを悪用した場合、悪用される可能性があるため、すべてのデザインパターンが悪用されたと結論付ける必要があります。そして、mySQLはmongoDBよりも悪いプレスを持っています:)あなたはそれが鍵であるという言葉「プレス」を知っています。プレスは単に感覚を求めているだけで、ジャーナリストは彼らが何を話しているのか本当にわかりません。

数学関数、誰か? Math.max()...単純な数学演算を実行するたびにオブジェクトを作成しないというのはいい考えですね。 :)

静的クラス-関数呼び出し間で状態やリソースを保持する必要がない場合に使用します(たとえば、数学関数を実行します。それぞれが前のものと無関係で、システムリソースを必要としません)。たとえばシングルトンを使用したロギング。FileSystemオブジェクトハンドルを何度も開いたり閉じたりしないようにするためです。

1
Slawek