4

ほとんどすべてのプロジェクトで、私はシングルトンパターンを実装するいくつかのクラスを作成します。たとえば、データ・マネージャ - ファイル・システム、データ・ローダーに関する作業がある場合 - アプリケーションがインターネット、さまざまなリソース・マネージャーなどに接続している場合など5-7までのクラスがあり、私がやっていると感じ始めます何か問題でも。シングルトンパターンをあまりにも多く使うのは悪い習慣ですか?プロジェクトのシングルトンが多すぎますか?悪い習慣ですか?

+0

コードで定義されたシングルトンは常に間違っています。高水準のドキュメンテーションで「このクラスのインスタンスは1つだけである」と定義されたシングルトンは許容されます。 – Raynos

答えて

4

シングルトンは必ずしもの問題ではありませんあまりにも)。 Singletonインスタンシエーションを持つクラスの決定を含め、アプリケーションのコンフィグレーションは、Spring for Javaなど、それを専門とする別のレイヤーに任せておく方がよいことが判明しました。同様に、管理レイヤーは、シングルトンと、特定のコンテキスト内のシングルトン(セッションの範囲内)と、常に新たに製造する必要があるシンプトンを見据えることができます。そのため、ビジネスロジックの作成に専念することができます。

シングルトンが問題となる可能性があり、管理/設定によってシングルトンが必要な理由の例は、データベースへの接続を管理するクラスを検討してください。あなたが言うかもしれないシングルトンのためのクラシックケース。あなたは、あなたのアプリが2つのデータベースへの接続を統合する必要があるほどに成長したことが分かるまで(それは起こる!)、それから全体の混乱を解消しなければならない。 がシングルトンを扱っているかどうかに関わらず、コードには依存しないようにしておけば、再構成するだけですべてを扱うことができます。いくつかのクラスは1つのDBに接続され、いくつかのクラスは他のクラスに接続されますが、これらのクラスは最小限の騒ぎでそれに乗ります。なぜなら、シングルトンが問題となる可能性があるもう一つの例は、コードのテストを書くときです。 (あなたはテストを書いていますか?)明示的なシングルトンは、構成が難しく、分離が難しいため、テストすることは非常に難しいです。あなたはそれらの多くを持つことを意味するので、テストの間にそれらを適切に破ることはできません。あなたのアプリが設定だけでシングルトンを使用する場合、テスト設定で簡単に変更することができ、テストをはるかに簡単に行うことができます。

1

このトピックについては多くの議論があります。一部の人にとっては、シングルトンはanti-patternとみなされます。しかしが非常に便利ですが、正しく実装するのは難しいと思われがちです。アプリケーション全体に共通のデータのためのユニークなエントリポイントを持つなど、その使用が正当化される状況があります。その中には厄介な部分があります。偽装されたグローバルな状態であり、データが不変の場合にのみ安全です。

JavaのEnterprise Editionの最新バージョンであるJEE6には、EJBコンポーネントとしてのシングルトンパターン用のsupportが含まれています。しかし、それについて考えてみてください、6つののリビジョンが最終的に完了しました!そのドメインの専門家である単一のオブジェクトは非常に役立ちます持つ - - しかし、明示的にオブジェクトにシングルトンらしをコーディングすることはほとんど常に悪い考えである(と頻繁にひどく行われ

1

プログラマーは、シングルトンをテストすることは苦痛であり、それを回避することをプログラマーが学んだことを知りました。接続マネージャ、リソースマネージャなどの必要なクラス/リソースを注入することで同じ効果を得ることができます。このように、テスト環境では、これらのクラスを簡単に擬似、注入、テストすることができます。

一方、場合によっては、インスタンスが1つしか存在しないことを保証するために、シングルトンを使用する方法が正しいと思われます。私。接続プールのために役立ちます。これは、その時点でインスタンスが1つしか存在しないことを保証し、リークは発生しません。 (注:シングルトンパターンのすべての実装が本当にこれを提供できるわけではありません。Javaでは正しい方法は列挙型を使用することです - 言語そのものが一意性を保証するためです。)

要約すると、私の答えははいです、あまりにも多くのシングルトンは悪いです。代わりにDI原則を使用することを検討してください

0

シングルトンの興味深い記事は反パターンですが、私はそれほど賛同しません。シングルトンをスタンドアローンのソリューションとして使ったことは一度もありませんでした。私はいつもそれをfactoryパターンと結びつけました。これは状態とカプセル化の議論を断ると思います。

シングルトン/ファクトリソリューションの良い例は、データベースクラスです。それぞれが独自の接続を必要とするいくつかのデータベースがあるかもしれませんが、すべての呼び出しでインスタンス化して新しい接続を作成する必要はありません。地雷が多すぎるのを避けるために共有接続をリサイクルしたいとします。線に沿って

何か:この例では

/** 
* Database manager for handling database related stuff 
* Does use Zend_Db and Zend_Config 
*/ 
class Database_Manager 
{ 
    protected static $dbos = array(); // Protected scope enforces encapsulation 

    public static function getDbo($name) 
    { 
     // Init 
     $hash = md5($name); 

     // Attempt to use singleton  
     if (array_key_exists($hash, self::$dbos)) { 
      return self::$dbos[$hash]; 
     } 

     // Your db connection settings are set here either via 
     // switch/case based on name, or loaded from a config file (yaml, xml, etc) 
     $dbConnectionParams = array('your', 'connection', 'settings'); 

     $config = new Zend_Config($dbConnectionParams); 

     $dbo = Zend_Db::factory($config->database); 

     // Adding to singleton so can be referenced in future calls 
     self::$dbos[$hash] = $dbo; 

     return $dbo; 
} 

シングルトンがすでにインスタンス化されたデータベース・オブジェクトを再利用しながら、工場は、カプセル化を確実にします。

終わりには、それはあなた次第で、あなたは道のりを支えたいものです。

関連する問題