1. ホーム
  2. xml

[解決済み] 依存性注入コンテナの利点は何ですか?

2022-12-08 01:19:30

質問

依存性注入の利点自体は理解しています。例えばSpringを例にとります。また、AOPやさまざまな種類のヘルパーなど、他のSpringの機能の利点も理解しています。ただ、XML構成の利点は何かというと、次のようなことです。

<bean id="Mary" class="foo.bar.Female">
  <property name="age" value="23"/>
</bean>
<bean id="John" class="foo.bar.Male">
  <property name="girlfriend" ref="Mary"/>
</bean>

のようなプレーンな古いJavaコードと比較して

Female mary = new Female();
mary.setAge(23);
Male john = new Male();
john.setGirlfriend(mary);

のように、より簡単にデバッグでき、コンパイル時にチェックされ、Javaしか知らない人でも理解できるようなものを作ることができます。 では、依存性注入フレームワークの主な目的は何でしょうか?(または、その利点を示すコードの一部)。


UPDATEです。

の場合

IService myService;// ...
public void doSomething() {  
  myService.fetchData();
}

myServiceの実装が複数ある場合、IoCフレームワークはどのようにインジェクトさせたい実装を推測するのでしょうか?もし、あるインターフェースの実装が一つしかなく、IoCコンテナに自動的にそれを使わせる場合、二つ目の実装が現れたら壊れてしまうでしょう。また、あるインターフェースの実装が意図的に1つしかないのであれば、インジェクションする必要はありません。

IoCの利点がわかるような小さな設定があれば、本当に面白いですね。私はしばらくの間Springを使っていますが、そのような例を提供することはできません。そして、私は、hibernate、dwr、および私が使用する他のフレームワークの利点を示す単一の行を示すことができます。


アップデイト2。

IoCの設定は、再コンパイルせずに変更できることを実感しています。それは本当に良いアイデアなのでしょうか?開発者でない人がリコンパイルせずにDBの認証情報を変更したい場合は理解できます。開発者以外の人がIoCの設定を変更することは、実務上よくあることなのでしょうか?開発者にとっては、設定を変更する代わりに、その特定のクラスを再コンパイルする努力は必要ないと思います。そして、非開発者のために、あなたはおそらく彼の人生を容易にするために、いくつかの簡単な設定ファイルを提供したいと思います。


UPDATE 3です。

インターフェースとその具体的な実装の間のマッピングの外部設定

外部化することの何がそんなに良いのでしょうか?ClassName.java.txtファイルに置いて、その場で手動で読み込んでコンパイルすれば、リコンパイルを回避できます。なぜコンパイルが避けられなければならないのでしょうか!

マッピングを手続き的なコードではなく、宣言的に提供するため、コーディング時間を節約できます。

宣言的なアプローチが時間を節約することがあるのは理解しています。例えば、私はビーンプロパティとDBカラム間のマッピングを一度だけ宣言し、Hibernateはロード、保存、HSQLに基づくSQLの構築などの際にこのマッピングを使用します。ここが宣言的アプローチが有効なところです。Springの場合(私の例では)、宣言の行数が多く、対応するコードと同じ表現力を持っています。もし、このような宣言がコードより短い例があれば、ぜひ見てみたいものです。

Inversion of Controlの原則により、実際の実装を偽物に置き換えることができるため、ユニットテストが容易になります(SQLデータベースをインメモリのものに置き換えるようなものです)。

私は制御の逆転の利点を理解しています (私はここで議論されているデザインパターンを依存性注入と呼びたいのですが、IoC はより一般的だからです - 多くの種類の制御があり、私たちはそのうちの 1 つだけを逆転させています - 初期化の制御です)。私は、なぜ誰かがそのためにプログラミング言語以外のものを必要とするのか、ということを聞いていたのです。私は、コードを使って本物の実装を偽物の実装に置き換えることができるのは確かです。そして、このコードはコンフィギュレーションと同じものを表現します - それは偽の値でフィールドを初期化するだけです。

mary = new FakeFemale();

DI の利点は理解しています。外部 XML 設定を行うことで、同じことを行うコードを設定することと比較して、どのような利点があるのかは理解していません。私は毎日コンパイルしていますし、まだ生きています。DI のコンフィギュレーションは、宣言的アプローチの悪い例だと思います。例えば、Hibernateのcfgでは、BeanのプロパティとDBのカラムのマッピングが保存、読み込み、検索クエリの構築などに使用されています。Spring DIの設定は、この質問の冒頭のように、簡単にコードの設定に変換することができますよね?しかも、Beanの初期化にしか使われないんでしょう?つまり、宣言的なアプローチでは、ここに何も追加されないということですよね?

hibernateのマッピングを宣言するとき、私はhibernateにいくつかの情報を与えるだけで、それに基づいて動作します - 私は何をすべきかを指示しません。Springの場合、私の宣言はspringに正確に何をすべきかを伝えます - なぜそれを宣言するのか、なぜそれをしないのか?


最終更新日です。

みんな、多くの回答が依存性注入について教えてくれていますが、私はそれが良いことを知っています。 質問は、コードを初期化する代わりにDI設定の目的についてです - 私はコードを初期化する方が短くて明確だと思う傾向があります。 私の質問に対する唯一の回答は、設定が変更されたときに再コンパイルを避けることができるというものでした。私は別の質問を投稿する必要があると思います。なぜこの場合にコンパイルが回避されなければならないのか、それは私にとって大きな秘密だからです。

どのように解決するのですか?

私自身は、IoC を使用する (そして外部設定を利用する) 主な理由の 1 つは、次の 2 つの領域です。

  • テスト
  • 生産保守

テスト

テストを3つのシナリオに分けた場合(大規模な開発ではごく普通のことです)。

  1. ユニット テスト
  2. 統合テスト
  3. ブラックボックステスト

最後の2つのテストシナリオ(統合テストとブラックボックステスト)については、アプリケーションのどの部分も再コンパイルしないことです。

テストシナリオのいずれかが構成を変更する必要がある場合 (たとえば、銀行統合を模倣するために別のコンポーネントを使用する、またはパフォーマンス負荷をかける)、これは簡単に処理できます (これは IoC の DI 側を構成する利点に該当します)。

さらに、アプリが複数のサイト(異なるサーバーとコンポーネント構成)で使用されるか、本番環境で構成が変更される場合、テストの後段でアプリがこれらの変更を処理できるかどうかを検証できます。

制作

開発者として、本番環境をコントロールすることはできません (特に、アプリが複数の顧客または別々のサイトに配布されている場合)。これは、IoC と外部設定の両方を使用する本当の利点です。

要約

IoC の外部構成がもたらす主な利点は、他の人 (非開発者) にアプリケーションを構成する力を与えることから生まれますが、私の経験では、これは限られた状況下でのみ役に立ちます。

  • アプリケーションが複数のサイト/クライアントに配布され、環境が異なる場合。
  • 本番環境とセットアップに対する、限られた開発コントロール/インプット。
  • テストシナリオ。

実際には、何かを開発するときに、それが実行される環境を制御することができても、時間が経つにつれて、設定を変更する能力を他の誰かに与える方が良いということがわかりました。

  • 開発時には、いつ変更されるかわかりません (アプリは非常に便利なので、あなたの会社はそれを他の誰かに販売します)。
  • 優れた構成モデルを設定して使用すれば対応できたはずのわずかな変更が要求されるたびに、コードを変更するのに手間取るのは嫌だ。

注: アプリケーションは (実行ファイルだけではなく) 完全なソリューションを指すので、アプリケーションが実行されるために必要なすべてのファイルが必要です。 .