依存関係注入を使用するときに「new」が必要になるケースはありますか?
-
22-08-2019 - |
質問
依存関係の注入は、「new」キーワードが不要になることを意味しますか?それとも、コレクションなどの単純なリーフ クラスを直接作成するのが合理的でしょうか?
以下の例では、コンパレータ、クエリ、dao を挿入していますが、SortedSet は直接インスタンス化されています。
public Iterable<Employee> getRecentHires()
{
SortedSet<Employee> entries = new TreeSet<Employee>(comparator);
entries.addAll(employeeDao.findAll(query));
return entries;
}
解決
私たちはすべてのためにそれを使用することを意味するものではありません。 DIを用いた場合であっても、多くの場合、の新しいのために必要があるでしょう。まだ新しい削除しないでください。
他のヒント
私が通常、依存関係の注入を使用するかどうかを決定する方法の 1 つは、テスト対象のクラスの単体テストを作成するときに、連携するクラスをモックまたはスタブする必要があるかどうかです。たとえば、クラスの単体テストを作成する場合、実際にはデータをデータベースに書き込む必要がないため、この例では (正しく) DAO を挿入しています。あるいは、連携クラスがファイルシステムにファイルを書き込むか、外部リソースに依存している可能性があります。または、動作が予測できないか、単体テストで説明するのが困難です。そのような場合は、依存関係を注入するのが最善です。
TreeSet のような連携クラスの場合、通常はこのような単純なクラスをモックアウトする必要がないため、これらを注入しません。
最後に 1 つ注意してください:何らかの理由でフィールドを注入できないが、テストでそれを模擬したい場合、私は次のことを見つけました。 Junit アドオン PrivateAccessor クラスのプライベート フィールドを、によって作成されたモック オブジェクトに切り替えることができると便利です。 イージーモック (または jMock またはその他の好みのモック フレームワーク)。
の新しいのそれはあなたのコードスニペットに示していますかのように使用しては何も問題はありません。
文字列のスニペットを追加したい場合を考えてみましょう。なぜあなたはStringBuilderのためのインジェクターをお聞きしたいですか?
私が直面してきた別の状況では、私は私のコンテナのライフサイクルに応じた実行中のスレッドを持つことが必要。その場合、私は、コンテナの起動のためのコールバックメソッドが呼び出された後、私のインジェクタが作成されたため、の新しいスレッド()のをしなければなりませんでした。インジェクタは準備ができていた後、私は手私のスレッドのサブクラスにいくつかのマネージクラスを注入します。
はい、もちろんます。
依存性の注入は、コンパイル時のクライアントが認識して(または選択を作ることができる)ではないかもしれないそれらのいくつかの可能なインスタンス化目標があるかもしれない状況のためのものです。
しかし、あなたがインスタンス化したい正確に何を知っています十分な状況がありますので、DIは必要ありません。
これは単にオブジェクト指向langaugesの関数を呼び出すようなものです:あなたは動的バインディングを使用することができるという理由だけで、(あなたは、いくつかの民間事業にあなたの方法を分割するときなど、)あなたは古き良き静的ディスパッチを使用できないことを意味するものではありませんます。
私の考えはDIも配線層とSTOが電位変化に柔軟である必要がありますあなたのコードの断片に素晴らしいと偉大であるということです。確かに我々はすべてが潜在的に変える必要があることができると言うことができますが、我々はすべて、実際にいくつかのものだけで文句を言わない触れたことを知っています。
DIが過剰であるとき、だから私は「新しい」を使用し、ちょうどそれがロールバックさせます。
例:私はコントローラー層へのビューにモデルを配線するために...それは常にDIを介して行われます。任意のアルゴリズムを私のアプリは、DIとも任意のプラグイン可能な反射コード、DIを使用しています。データベース層.. DIはなく、かなり私のシステムで使用されている他のオブジェクトは、共通の「新規」で処理されます。
は、このことができます願っています。
今日は、フレームワーク主導型の環境で、あなたが少なく、オブジェクトをインスタンス化すること本当です。例えば、サーブレットがサーブレットコンテナによってインスタンス化され、スプリングでインスタンススプリングの豆等
永続化層を使用しているとき、彼らは持続してきた前に、それでも、あなたはあなたの持続オブジェクトをインスタンス化します。休止状態を使用している場合、たとえば、あなたのHibernateTemplateを節約呼び出す前に、あなたの持続オブジェクトに新しい呼び出します。