52

Java EEでCDIを使用する方法を説明する記事がたくさんあることは知っていますが、これが実際にどのような利点をもたらすのか理解するのに苦労しています。たとえば、現在Fooのインスタンスを使用しているクラスがあるとします。私はどちらかをするかもしれません

Foo myFoo = new Foo();

また

// Better, FooFactory might return a mock object for testing    
Foo myFoo = FooFactory.getFoo();

私はCDIでそれを読み続けています:

@Inject
Foo myFoo;

しかし、なぜこれが以前のファクトリベースのアプローチよりも優れているのでしょうか?私が気付いていない他のユースケースがあると思いますが、これを特定することはできませんでした。

以下の応答を理解した場合、概念は、DIフレームワークが一元的に構成されたマスターオブジェクトファクトリとして機能するということです。これは合理的な解釈ですか?

アップデート

それ以来、私はSpringを学び始めましたが、これは今ではもっと理にかなっています。以下の段落は、Spring in PracticeAccountServiceから抜粋したもので、。のインスタンスを使用するクラスの例を取り上げていますAccountDao。長い引用をお詫びしますが、注入されたリソースが標準の初期化よりも何かを提供する理由の核心にあると思います。

newキーワードを使用してAccountServiceを構築することもできますが、サービスレイヤーオブジェクトの作成がそれほど簡単になることはめったにありません。多くの場合、DAO、メール送信者、SOAPプロキシなどに依存します。AccountServiceコンストラクターで(または静的初期化を介して)これらの各依存関係をプログラムでインスタンス化できますが、それらがスワップアウトされると、ハードな依存関係とカスケード変更が発生します。

さらに、依存関係を外部で作成し、setterメソッドまたはコンストラクター引数を介してAccountServiceに設定できます。そうすることで、ハードな内部依存関係が排除されます(AccountServiceでインターフェースによって宣言されている限り)が、初期化コードはどこにでも複製されます。DAOを作成し、それをAccountServiceにSpringの方法で接続する方法は次のとおりです。

<bean id="accountDao" class="com.springinpractice.ch01.dao.jdbc.JdbcAccountDao"/>

<bean id="accountService"
    class="com.springinpractice.ch01.service.AccountService">
    <property name="accountDao" ref="accountDao"/>
</bean>

上記のようにBeanを構成すると、プログラムはAccountServiceSpring ApplicationContextからのインスタンスを要求できるようになり、SpringDIフレームワークはインスタンス化が必要なすべてのものをインスタンス化した後の処理を行います。

4

4 に答える 4

49

CDIを書いた人々は、あなたに1つの大きなオブジェクトファクトリを与えました。彼らはあなたのために、あなたよりもうまく仕事をしてくれました。これはXML構成または注釈駆動型であるため、すべてをコードに埋め込む必要はありません。

Springのような依存性注入エンジンは、工場よりもはるかに多くのことを行います。それらが提供するすべてを複製するには、複数のファクトリクラスと1行のコードが必要になります。

もちろん、使用する必要はありません。あなたはいつでもあなた自身の車輪を自由に発明することができます。そして、あなたがすべきこと-あなたの目的が車輪を作る方法や依存関係を排除する方法を学ぶことであるなら。

ただし、アプリケーションを開発するだけの場合は、他の人が提供するツールを使用することをお勧めします。

依存性注入に関する独創的な記事は、 MartinFowlerによって書かれました。私はそれを読むことをお勧めします。8年経った今でも素晴らしいです。

「それ以上のものがまだはっきりしていない」

ここにいくつかの利点があります:

  1. ルーザーカップリング
  2. より簡単なテスト
  3. より良いレイヤリング
  4. インターフェイスベースの設計
  5. 動的プロキシ(AOPへのセグエ)。
于 2012-10-24T11:01:35.757 に答える
19

依存性注入を使用する目的は、注入されたものを使用するコードがファクトリに依存しないようにすることです。ファクトリコードの例では、DIアプローチでは必要のない静的メソッド呼び出しがコードに埋め込まれています。

注入されているものはmyFoo、工場について知る必要はありません。工場では、DIにはないテストのオプションに制限を設けています。具体的には、Fooを持つBarオブジェクトがある場合、そのBarオブジェクトのテストでFooまたはモックFooを直接作成し、FooFactoryを使用せずにBarに配置でき、FooFactoryを作成する必要はありません。これは、アプリケーションのビジネスロジックを実装するために何もしない定型文です。

于 2012-10-24T11:49:29.053 に答える
5

これは、エンタープライズプログラミングとは何かについての重要で微妙な質問です。

名前は適切に選択されています:コンテキストと依存関係。

CDIは、より優れた、またはよりクリーンなコードとは何の関係もありません。大規模な組織が複雑な分散ソフトウェアシステムを構築し、データを共有できるようにすることです。それは、政府や他の官僚が、管理するすべてのソフトウェアに対して、自己完結型の十分に文書化されたパッケージを無差別に配布できることを100%確実にすることです。最近では、事実上すべてのPOJOを注入できることを忘れないでください。

ある種のクライアントアプリを作成していて、その隅にユーザーの名を印刷したいとします。

  • この大企業のエンタープライズアーキテクトはあなたにこの機能を持たせたいと思っていますが、ジュニアソフトウェアエンジニアとして、あなたがDBの鍵を渡される可能性はありません。

  • また、ネットワーク全体でデータを保護したいと考えていますが、データのスクラップを共有する必要があるたびに、認証クライアントを再設計するためにエンジニアにお金を払っていません。

  • 彼らはあなたがこの情報を照会して更新できるようにしたいと思っていますが、トランザクションがどのアプリよりも高いレベルで処理されることを望んでいます。

  • 彼らは、セットアップブロックで些細なモックを使ってクラスをテストできるようにしたいと考えています。

  • 彼らは、クラス間の結合に最小限の静的メソッドを含めることを望んでいます。

  • そして何度も何度も...

ほとんどのJSRには、おそらく「EAができることを望んでいる...」がどこかに埋め込まれています。

CDIは、大きな(任意の?)水平および垂直スケールのアプリがコンテキスト、依存関係、したがってデータを共有できるため、好まれます。

ファウラーの言葉で:

「問題は、リスタークラスが実装クラスを認識しないようにそのリンクを作成する方法ですが、それでもインスタンスと通信してその作業を行うことができます。」

「しかし、このシステムをさまざまな方法でデプロイしたい場合は、プラグインを使用してこれらのサービスとの相互作用を処理し、さまざまなデプロイメントでさまざまな実装を使用できるようにする必要があります。」

「これらのコンテナーが使用するアプローチは、プラグインのすべてのユーザーが、別のアセンブラーモジュールが実装をリスターに挿入できるようにする何らかの規則に従うようにすることです。」

一言で言えば、それらは複雑なエンタープライズアプリケーションの集中化された「コマンドアンドコントロール」を可能にします。 Java EEは、体系化された信頼性の高い抽象化プロセスであり、CDIはその化身であり、非常にうまく機能し、ほとんど見えなくなります。これにより、複雑なアプリをつなぎ合わせるのはほとんど簡単になります。

さらに2つのこと:

  1. CDIは、Java EEではJNDIと呼ばれる「サービスロケーターパターン」と平和的に共存していることに注意してください。これは、クライアント開発者が多くの同じタイプの選択肢から選択する必要がある場合に適しています。

  2. CDIは、多くの場合、特に非企業(文字通り)の場合に必要とされるよりも多くの火力です。

于 2015-01-05T00:08:21.783 に答える
4

高レベルでは、CompSciのほとんどのものと同様に、アプリケーションでとしてハードコーディングされる間接参照(または抽象化)のレベルを提供しますFoo myFoo = new Foo();。その間接参照により、緩く結合されたコードが生成され、モジュール化されて、クラスやサブシステムの置き換え、サービス、テストなどが簡単になります。

間接/抽象化には多くの設計とパターンがあることに注意してください-依存性注入は1つにすぎません。

あなたの質問のもう一つの側面は「なぜCDIなのか」です。-ええと、誰かがあなたのためにすでに仕事をしているからです。いつでも独自のものを構築できますが、予算内で時間どおりに実行する必要のある実際のシステムを構築することが目的である場合、通常は時間の無駄です。ミシュランの星を獲得したシェフがあなたのためにその仕事を喜んでやってくれるのに、なぜ食料品や料理に悩むのですか?

于 2013-12-21T18:47:33.377 に答える