DIを使用する場合とJavaで自分を作成する場合


8

私はさまざまな言語でまともな量のOOPを使用していますが、Javaはかなり新しいものです。

私はクラスのコード内に多数のオブジェクトが作成される多くのチュートリアルを読んでいますが、それらを実行しようとしていますが、チュートリアルでクラスのバージョンを構築します。クラス自体。

しかし、Javaは私が使用した他の言語とは異なり、ほとんどすべてがオブジェクトです。文字通りすべてを注入すると、結果は非常に複雑で追跡が困難になります。

明らかに、あなたはStringオブジェクトをインジェクトしないでしょう、そしてインジェクトしない他のオブジェクトがあると思いますが、行がどこに行くべきかわかりません。どの時点で、DIは正しいことをやめ、いつ負荷がかかり始めるのでしょうか?何を注入し、何をインスタンス化するかを実用的にどのように決定しますか?

参考までに、私が実行しているチュートリアルは、単純なクライアントを構築するためのhttp://edn.embarcadero.com/article/31995およびhttp://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.htmlです。サーバ。私はそれらを行ごとにコピーしていませんが、ベストプラクティスに従う同等のクラスを作成しようとしています


1
この質問は、Javaではありませんが、それほど厄介な方法で「注入のすべて」への方法について協議: programmers.stackexchange.com/questions/190120/...
JeffO

回答:


4

.Net(これはすべてがオブジェクトであるという点で似ています)では、主にドメインオブジェクト(エンティティ、リポジトリ、サービス)とアプリケーションオブジェクト(コントローラー、ビューモデル)でDIを使用するため、リポジトリ/サービスがコントローラーに注入されます/ viewモデルなど。これは、私のビジネスロジックとアプリケーションロジックが完全にテスト可能であることを意味します。これが、私がDIを使用する主な理由です。

基本的に、あなたが注入したり、物を注入したりするオブジェクトは、ほとんどがあなたが構築しているソリューションに固有のオブジェクトです。一部のオブジェクトが言語またはフレームワーク(.Netなど)に対して「ネイティブ」である場合、おそらくそれを注入する必要はありません。多くのオブジェクトは、データを表すために文字列を必要とします。文字列は基本的に、ドメインに固有ではない「言語機能」です。同じことは、列挙型、リスト、配列、および他の多くのものにも当てはまりますが、システムの他の部分から分離してクラスを実行するときに変更する必要はありません。

確認する最も重要なことは、ドメイン/アプリケーションクラス間の結合です。オブジェクトが密結合をもたらさない場合、通常はそれを作成するだけで安全です。結合をチェックする方法の1つは、クラス内のメソッドを分離して実行することです(これは基本的にユニットテストです)。テストするクラスが実際にシステムから分離して実行されていることを確認するために、DI化する必要があるのは、モックアウトする必要があるすべての依存関係です。


それを見る別の方法は、クラスまたはメソッドが何をしようとしているのかということです。典型的な例は、オブジェクトを保存することです。そのクラス/メソッド内のロジック、オブジェクトを保存するオフつもりはないとの接続などを作成するためのボイラープレートの仕事をやってする必要があり、サービス/リソースのその種が/でDI'dしなければならない可能性があります。
マルタインVerburg

4

まず、新しいキーワードを使用しても問題ありません。DIは素晴らしいテクニックですが、使い過ぎる誘惑があります。DIを使用する可能性があるのは次のような場合です。

  • ダブルスのテスト-サードパーティのリソース(フルOracle DBなど)を起動したくないので、ユニットテストではサードパーティのリソースをモックアウト/ダブルテストしたいことがよくあります。たとえば、大きなOracle DBへの新しいデータベース接続を作成する代わりに、その接続をHSQL(メモリデータベース内)への接続に置き換えることができます。

  • そのオブジェクトのスコープ(〜ライフスパン)を制御する必要があり、自然なJavaオブジェクトのライフサイクルが機能しない場合。多くのJavaベースのDIフレームワークでこれを行うことができます。

  • シングルトンが必要な場合。

  • ファクトリー、サービスロケーターなどが必要だと思うときはいつでも。これには、異なるファクトリが必要な場合も含まれます(まれですが、起こります)。

それ以外の場合は、単に新しいオブジェクトを作成します。実際に疑わしい場合は、新しいオブジェクトを作成します。後で必要になったときにいつでもDIを作成できます:-)。


あなたの最初のポイントは絶対に何を意味するかもしれないので、あなたが質問にどのように答えたかはわかりません。また、DIを使用してファクトリを構築するのではなく、DIを使用してファクトリを注入する方がはるかに優れたソリューションであることを多くの場所で見たので、最後の点についても疑問があります。
pdr 2013年

ポイントをもう少し明確にするために編集
Martijn Verburg 2013年

Test Doublesというフレーズを聞いたことがありません。実際のdocs.oracle.com/javase/6/docs/api/java/lang/Double.htmlをテストすることを意味していると思いました
NimChimpsky 2013年

1
@NimChimpskyテストダブルは、モック、スタブ、またはその他の代用の総称です。xunitpatterns.com/Test%20Double.html

0

ウィキペディアから:

依存関係注入パターンの主な目的は、コンパイル時ではなく、実行時に、または構成ファイルを介して、特定の依存関係インターフェースの複数の実装から選択できるようにすることです。このパターンは、テスト時に複雑なコンポーネントのスタブテスト実装を提供するのに特に役立ちますが、プラグインコンポーネントの検索や、初期化と検索によく使用されます。

文字列を注入する必要はありません。それらをパラメータとして関連メソッドに渡すだけです。configからデータを注入する必要はありません。

優れた単体テストは、エラーを特定するのに役立ちます。そのため、コードを他のコード単位とは別にテストする必要があります。DIはこれを達成するのに役立ちます。


0

一般的に、クラスはnew他の1つのクラスからのみ取得する必要があります。

これは、依存関係注入の道を進むと、使用しnewているすべてのオブジェクトが、作成するオブジェクトのすべての依存関係を注入する必要があるためです。つまり、親オブジェクトはこれらの依存関係もすべて知っている必要があります。場合Aに依存しているBし、C作成Aしてインスタンスをnew、その後C、自動的に依存関係を持つ必要があるB場合でも、C使用することはありませんB直接。まず、Csを作成することが唯一の仕事でない限り、それは懸念の分離に違反しますA。そうしないと、依存関係を追加したい場合に問題が発生します。これは、依存関係をA作成するすべてのものが同じ依存関係を追加する必要があるためです。彼らは本当にそれについて心配するべきではありません。持っている方がいいCへの依存関係を宣言し、依存関係AFactoryAFactory持っていBます。次に、必要なものAすべてに依存関係を追加できAFactory、変更するだけです。


-1

「どの時点でDIが正しいことをやめ、いつ負荷がかかり始めるのですか?...」

まず第一に私はDIが好きでそれをたくさん使うので私を誤解しないでください

DIはサーバー側に最適ですが、Guiプログラミングに関してはゲームが一変します。たとえば、Swingで開発された既存のGUIアプリにGuiceを組み込んだ

  • 静的ファクトリー、ネストされた依存関係などを取り除くには、たくさんリファクタリングする必要があります。
  • たとえば、DIコンテナーがオブジェクトを作成/処理する方法に注意する必要があります。たとえば、起動時にオブジェクトを熱心に作成すると、パフォーマンスの問題が発生する可能性があります(特にGUIアプリでは15〜40秒の遅延が問題になります)。DIコンテナーが許可する設定を、週単位で使用できます。
  • DIを既存のプロジェクトに組み込むには、進化よりも革命が必要

ネストされた依存関係を処理する方法は?

深くネストされたクラスのいくつかの依存関係にアクセスする必要があるとしましょう。DIは次のいずれかの方法で使用できます。

  • コンストラクターを注入するようにコンストラクターを変更します(コンストラクターが多くのパラメーターを取るようになっていることを知っている...)?
  • フィールドインジェクションを使用する(フィールドを公開しているため、これは適切なソリューションではありません)
  • セッターインジェクションを使用します(コードで不要なセッターを作成する必要があることを理解してください)

どの程度あなたが(オブジェクトの必要性は、いくつかのcriterisに応じて、実行時に作成されるため))(新しいを使用してオブジェクトを作成したいと容器にそれを登録したい場合(Guiceには、ハンドルは、新しい()で作成したオブジェクトはありませんしています良い)?したがって、アプリで新しい機能を開発するのではなく、コンテナに焦点を戻す必要があります。

DesignPatterns +創造的思考と優れたアーキテクチャ設計を使用するいくつかの場合の最後の言葉は、DIの導入の結果としてゲインが小さく、面倒が高まる状況を回避できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.