以下の答えは間違っていますが、私は他の人がそれから学ぶためにそれを保ちます(以下を参照)
ではExampleA
、Config
複数のクラスで同じインスタンスを使用できます。ただし、Config
アプリケーション全体でインスタンスが1つしかない場合は、シングルトンパターンを適用して、のConfig
インスタンスが複数存在しないようにすることを検討してくださいConfig
。Config
シングルトンの場合は、代わりに次のようにできます。
class ExampleA
{
private $config;
public function __construct()
{
$this->config = Config->getInstance();
}
}
$exampleA = new ExampleA();
ExampleB
他の一方で、あなたはいつもの別個のインスタンス買ってあげるConfig
の各インスタンスについてをExampleB
。
どのバージョンを適用する必要があるかは、アプリケーションが次のインスタンスを処理する方法によって異なりますConfig
。
- の各インスタンスに
ExampleX
の個別のインスタンスが必要な場合はConfig
、に進みExampleB
ます。
- の各インスタンスがのインスタンスを
ExampleX
1つだけ共有する場合はConfig
、を使用しExampleA with Config Singleton
ます。
- のインスタンスがの
ExampleX
異なるインスタンスを使用する可能性がある場合はConfig
、に固執しExampleA
ます。
シングルトンConfig
への変換が間違っている理由:
昨日はシングルトンパターンについてのみ学んだことを認めなければなりません(デザインパターンのヘッドファーストの本を読んでいます)。単純に私はこの例にそれを適用しましたが、多くの人が指摘したように、ある方法は別の方法です(いくつかはより不可解で、「あなたはそれを間違っている!」とだけ言っています)、これは良い考えではありません。したがって、私がしたのと同じ過ちを他の人がするのを防ぐために、シングルトンパターンが有害である理由の概要を次に示します(コメントと私がそれをグーグルで見つけたものに基づいて):
場合ExampleA
に独自の基準取得Config
のインスタンスを、クラスが緊密に結合されます。のインスタンスExampleA
を使用してConfig
(のサブクラスなど)別のバージョンを使用する方法はありません。に提供する方法がないためExampleA
、のモックアップインスタンスを使用してテストする場合、これは恐ろしいことです。Config
ExampleA
前提は1、そして唯一のだろう、のインスタンスがConfig
多分保持し、今、あなたは常に同じ意志ホールドていることを確認することはできません将来的には。後でいくつかのインスタンスConfig
が望ましいことが判明した場合、コードを書き直さずにこれを実現する方法はありません。
の唯一無二のインスタンスがConfig
すべての永遠に当てはまるかもしれませんが、Config
(まだインスタンスが1つしかない)のサブクラスを使用できるようにしたい場合があります。ただし、コードはメソッドであるgetInstance()
of を介してインスタンスを直接取得するため、サブクラスを取得Config
するstatic
方法はありません。ここでも、コードを書き直す必要があります。
をExampleA
使用Config
するという事実は、少なくとものAPIを表示しているだけでは非表示になりますExampleA
。これは悪いことかもしれませんし、そうでないかもしれませんが、個人的には、これは不利に思えます。たとえば、維持する場合、Config
他のすべてのクラスの実装を調べずに、変更によって影響を受けるクラスを見つける簡単な方法はありません。
シングルトンをExampleA
使用すること自体が問題ではない場合でも、テストの観点からは問題になる可能性があります。シングルトンオブジェクトは、アプリケーションの終了まで存続する状態を保持します。あるテストを別のテストから分離したいので、これは問題になる可能性があります(つまり、1つのテストを実行しても、別のテストの結果に影響を与えてはなりません)。これを修正するには、テスト実行のたびに(場合によってはアプリケーション全体を再起動する必要がある)シングルトンオブジェクトを破棄する必要があります。 Config
とはいえ、実際のアプリケーションの実装ではなく、ここでこの間違いを犯してよかったと思います。実際、実際に最新のコードを書き直して、一部のクラスにシングルトンパターンを使用することを検討していました。変更を簡単に元に戻すことはできますが(もちろんすべてがSVNに保存されています)、それでも時間を無駄にしていました。