web-dev-qa-db-ja.com

シングルトンがアンチパターンと見なされるのはなぜですか?

可能性のある複製:
シングルトンの何がそんなに悪いの?

シングルトンデザインパターン:落とし穴

シングルトンアンチパターン

最近、シングルトンはアンチパターンであると聞きました。クラスのシングルトンを作成することは、その一意のインスタンスをグローバル変数にすることに関係しますが、それ以上のことも行います(そのオブジェクトのインスタンス数の制限、インスタンス化の管理など)。

なぜシングルトンはまさにアンチパターンと見なされるのですか?そして、代替手段は何ですか?

69
user1710031

回答を支援するために、アンチパターンコメントについて詳しく説明します。

過度に使用され、クラスの唯一のインスタンスが実際に必要とされない状況で不必要な制限を導入し、アプリケーションにグローバルな状態を導入します

From: http://en.wikipedia.org/wiki/Singleton_pattern

詳細については、次を参照してください。 https://www.michaelsafyan.com/tech/design/patterns/singleton

上記のブログのすばらしい結末は次のとおりです。

要するに、シングルトンパターンにより、コードがより複雑になり、有用性が低くなり、再利用やテストが非常に難しくなります。シングルトンを排除するのは難しい場合がありますが、やりがいのある努力です。

OK、それで、それがアンチパターンである理由はこの段落でよく説明されており、著者が表現しているように、それはあなたのコードをシングルトンにしっかりと結び付けています。

シングルトンを使用したい場合は、デザインを検討することをお勧めしますが、便利な場合があります。

たとえば、一度に何千ものリクエストを処理するために、最大で1つのデータベース接続を持つアプリケーションを作成する必要がありました。したがって、私は1つのインスタンスしか持たないリソースに制約されているため、シングルトンは理にかなっています。

しかし、一般的にこれは導入される困難を考えずにコードを単純化するために使用されます。

たとえば、これは静的クラスにも適用されます。ユニットテストまたは同時実行性がある場合、1つのリクエストの状態によって状態が変化し、インスタンスを呼び出すクラスが状態を想定しているため、問題が発生する可能性があります期待した。

使用に挑戦する最良の方法は、プログラムがマルチスレッドである場合の処理​​方法を考えることであり、それを行う簡単な方法は、一度に実行される複数のテストがある場合、ユニットテストを行うことだと思います。

それでも必要な場合は、それを使用しますが、後で発生する問題を認識します。

63
James Black

私は、シングルトンがアンチパターンであると厳密に考えているわけではありません。

ただし、シングルトンは基本的にグローバル変数を使用する方法です。また、システム内のどこのコードでも値を変更できるため、グローバル変数は不良です。そのため、デバッグの際に、どのコードパスがシングルトンの現在の状態につながるかを把握するのは困難です。

19
Jack Edmonds

シングルトンクラスは他のオブジェクトによって通常の方法でインスタンス化できないため、アンチパターンと見なされると思います(「getInstance」という名前のこのようなメソッドを呼び出すことを除く)。したがって、最初に使用可能なオブジェクトを作成するためにインスタンス化せずに、クラスが直接使用されているように見えます。

シングルトンはグローバルな一意のインスタンスとして機能できることに同意します。一部の人々から、シングルトンの代替として、静的変数および/または最終変数を使用でき、列挙も使用できることを学びました(したがって、複数の変数を1つのグループ名でグループ化することができます通常のクラス/オブジェクト)。

ただし、これらの選択肢は、状態/値の保存におけるシングルトンクラスの機能とのみ一致します。一意の関数を使用する必要がある場合、それらの静的/最終変数と列挙型は役に立ちません。私の意見では、これはシングルトンクラスを使用する必要がある場合(静的/最終状態/値を操作するためにいくつかの一意の関数が必要な場合)です。

乾杯... :))

10
peter.aryanto

シングルトンは、多くの場合、適切に実装されていません。ダブルチェックロックを参照してください。

どのスコープでシングルトンインスタンスが一意である必要があります。マルチスレッド環境、クラスタリングなど。

シングルトンはテストが難しい場合があります。

シングルトンに割り当てられたメモリは解放できません。

シングルトンを過度に使用すると、オブジェクト指向プログラミングから手続き型プログラミングに任せます。

6
daniel