[解決済み] 依存性注入コンテナの利点は何ですか?
質問
依存性注入の利点自体は理解しています。例えば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つのシナリオに分けた場合(大規模な開発ではごく普通のことです)。
- ユニット テスト
- 統合テスト
- ブラックボックステスト
最後の2つのテストシナリオ(統合テストとブラックボックステスト)については、アプリケーションのどの部分も再コンパイルしないことです。
テストシナリオのいずれかが構成を変更する必要がある場合 (たとえば、銀行統合を模倣するために別のコンポーネントを使用する、またはパフォーマンス負荷をかける)、これは簡単に処理できます (これは IoC の DI 側を構成する利点に該当します)。
さらに、アプリが複数のサイト(異なるサーバーとコンポーネント構成)で使用されるか、本番環境で構成が変更される場合、テストの後段でアプリがこれらの変更を処理できるかどうかを検証できます。
制作
開発者として、本番環境をコントロールすることはできません (特に、アプリが複数の顧客または別々のサイトに配布されている場合)。これは、IoC と外部設定の両方を使用する本当の利点です。
要約
IoC の外部構成がもたらす主な利点は、他の人 (非開発者) にアプリケーションを構成する力を与えることから生まれますが、私の経験では、これは限られた状況下でのみ役に立ちます。
- アプリケーションが複数のサイト/クライアントに配布され、環境が異なる場合。
- 本番環境とセットアップに対する、限られた開発コントロール/インプット。
- テストシナリオ。
実際には、何かを開発するときに、それが実行される環境を制御することができても、時間が経つにつれて、設定を変更する能力を他の誰かに与える方が良いということがわかりました。
- 開発時には、いつ変更されるかわかりません (アプリは非常に便利なので、あなたの会社はそれを他の誰かに販売します)。
- 優れた構成モデルを設定して使用すれば対応できたはずのわずかな変更が要求されるたびに、コードを変更するのに手間取るのは嫌だ。
注: アプリケーションは (実行ファイルだけではなく) 完全なソリューションを指すので、アプリケーションが実行されるために必要なすべてのファイルが必要です。 .
関連
-
SAXParseException: ルート要素に続くドキュメント内のマークアップは、うまく処理されなければなりません。
-
[解決済み] XMLの<![CDATA[]]>は何を意味するのですか?
-
[解決済み] Spring Frameworkの@Injectと@Autowiredの違いは何ですか?どのような条件でどちらを使うか?
-
[解決済み] Inversion of ControlとDependency Injectionの比較
-
[解決済み] なぜ依存性注入を使用するのですか?
-
[解決済み】フィールド・インジェクションとは何ですか、またそれを回避する方法は?
-
[解決済み] XMLで属性値を取得する
-
[解決済み] XML SchemaとDTDの違いは何ですか?
-
[解決済み] Notepad++:ファイルを読み込むときに自動的に言語をXmlに設定する方法
-
[解決済み] XPathを使用して、次の兄弟/XMLタグを選択する方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] XML文書でエスケープする必要がある文字は何ですか?
-
[解決済み] XMLでタグのブロックをコメントアウトするにはどうすればよいですか?
-
[解決済み] XMLの属性値で二重引用符をエスケープするには?
-
[解決済み] XML スキーマ。テキストのみを含む属性を持つ要素?
-
[解決済み] XMLサイトマップのContent-Typeはどのような値ですか?
-
[解決済み] XMLで一行だけコメントするにはどうしたらいいですか?
-
[解決済み] Eclipseです。log4j.xml 内の log4j.dtd を参照する。
-
[解決済み] Androidでカスタム書体を使用する
-
[解決済み] XSDでelementFormDefaultは何をするのですか?
-
[解決済み] xs:NCName型とは何ですか、そしてそれはいつ使うべきですか?