2

データベースと相互作用するシステムがあるとします。システムはデータベースを非常に頻繁に使用するため、ほぼすべてのサブルーチンは次のパターンに従います。

foo(database, rest, of, arguments)

これはすぐにわかります。fooはより大きなオブジェクトの一部であるため、接続変数はオブジェクト変数に移動されます。残念ながら、これはすべてのモデルオブジェクトのコンストラクターがこの引数を取ることを意味します。

そこで、データベースへの接続を生成できるモジュールを作成することにしました。データベースへの接続にはコストがかかるため、接続はキャッシュされ、そのキャッシュされた値は将来の呼び出しで返されます。

作成したのはシングルトンです。これは、開発コミュニティで一般的に嫌われているパターンです。繰り返しになりますが、DRYは推奨される原則であり、シングルトンパターンが推奨されない場合よりもさらに重要です。

では、どちらが良いですか?オプションは、すべての関数呼び出し(または少なくともコンストラクター)に入る引数の数を増やすか、シングルトンを作成することです。私が見ない3番目のオプションはありますか?

編集:シングルトンに反対する記事はhttp://blogs.msdn.com/b/scottdensmore/archive/2004/05/25/140827.aspxです。そこで提示された議論は理にかなっていると思います。私は、反シングルトン陣営がこの設計問題の解決策を持っていることを望んでいました。

4

3 に答える 3

2

DRYは、 「シングルトンを使用しない」よりもはるかに重要です。そのような原則が実際に誰かによって明確にされている場合(たとえば、「シングルトンをひどく誤用しないでください」とは対照的に)。両方を満たすことができれば自由ですが、どちらか一方だけを満足させる必要がある場合は、DRY を満足させてください。

于 2012-07-13T19:49:29.400 に答える
1

ルックアップまたはインジェクション パターンを検討することもできます。接続の詳細を含むシングルトンを 1 つ作成し、接続が必要なすべてのクラスで「ルックアップ」を使用するか、それをクラスに注入するシステムを作成します。乱用が問題につながる可能性がある場合でも、共有リソースの場合、これらのアプローチは私にとって非常に理にかなっています。

于 2012-07-13T19:51:41.830 に答える
0

シングルトンは、グローバル変数をシステムに導入する方法として使用された場合、悪いと見なされます。

変数として実装されたシングルトンstaticは、テスト用に簡単にモック化できないため、良くありません。静的であるため、注入されず、依存関係が隠されます。あなたが今行っている議論は、あなたのコード全体でこの依存関係を目にすることによって促されました。それは素晴らしい!あなたはコードを聞いて、より良い設計を見つけようとして反応しています。データベースへのアクセスが静的なエントリ ポイントを介して行われた場合、依存関係の急増に気付かなかったでしょう。

クラスの単一の共有インスタンス (通常はサービスとして) を使用する複数のオブジェクトの概念は、完全に有効な設計です。このように考えると、すべてのサービス オブジェクトは一種の「スコープ付きシングルトン」になります。IE このサブシステム内には、X のインスタンスが 1 つだけ存在します。正しく実装されていれば、これは配線の決定であり、クラスの実装の決定ではありません。IEでは、クラスを1つだけ作成し、同じインスタンスを必要な人に渡すことで、任意のクラスをシングルトンとして使用できます...問題のクラスは、それがシングルトンであることを知りません。

「データベース」を多くのオブジェクトに渡すのは臭いことに同意します。「データベース」へのすべての呼び出しを、厳密に型指定された Repository オブジェクトに分解します。それぞれにクリーンなインターフェイスがあり、呼び出し元は、データがどのように取得またはドメイン オブジェクトに変換されるかを心配することなく、必要なデータ セットを要求できます。次に、必要なリポジトリを、呼び出しごとに渡すのではなく、以前にデータベースを使用していたクラスのコンストラクターに挿入します。「依存性注入」を行っている場合、ワイヤリング コードがオブジェクトの外に出て、ファクトリ クラスに移動することがわかります。これらのファクトリは、実際にリポジトリをクエリする必要があるクラスにのみリポジトリを挿入します。

私が見たパターンの 1 つは、オブジェクトが実際には必要のない依存関係を取得することです。これは、作成した他のオブジェクトにそれを渡すためです。これは、この「ファクトリ」動作を独自のクラスに分解することによって防止されます。

とにかく..短い答えは、「掘り続けて..単一責任の原則と依存性注入を適用して拡散を制限するために、なぜ非常に多くのクラスがデータベースアクセスを必要とするのかを解明する」です。

于 2012-07-23T22:56:31.443 に答える